Frudy
6k
2020-12-09 00:01:21
10
2974

경고를 무시하면 생기는 일 (ts-ignore)


회사에서 생긴 경험을 공유하고자 글을 작성합니다.


마땅한 예제 코드가 없어서... 예시는 가볍게 봐주세요!


function sizeToState(data: {size: number} | undefined | null): 'big' | 'small' | '?' {

if (data === null || data === undefined) {
return '?';
}

if (data.size > 60) {
return 'big';
}

return 'small';
}

size를 크다 작다 혹은 ? 3개중 하나를 반환하는 함수입니다.


if (data === null || data === undefined)

if문을 이렇게 작성하고 return하게 될경우


밑에 data들은 이렇게 타입이 추론되는것을 보실 수 있습니다.

(이것을 타입가드라고 합니다)


하지만,

if ([undefined, null].includes(data)) {
return '?';
}

이렇게 고쳐쓰면 타입가드는 작성하지않습니다.

=== null || === undefined로 쓰나 includes로 쓰나 똑같은데말이죠.


심지어, 저렇게 includes로 사용하면,

TS2345: Argument of type '{ size: number; } | null | undefined' is not assignable to parameter of type 'null | undefined'.


이런 에러까지 뜨고 그럽니다.

그렇습니다. Typescript가 타입체크를 해주는것은 한계가 있습니다.


그래서 저는 이런 한계를 만나는 경우,

//@ts-ignore
if ([undefined, null].includes(data)) {
return '?';
}

이렇게 무시를 하곤 했습니다.


그리고,

if (data.size > 60) {
return 'big';
}

위에서 타입가드가 작동하지않았으므로, 밑에서도 당연히 타입에러가 발생합니다.

아직 data는 undefined일지도 null일지도 모르는데

size라는 프로퍼티로 접근하는 코드가 저렇게 있으니까요.


그래서 이마저도

//@ts-ignore
if ([undefined, null].includes(data)) {
return '?';
}

//@ts-ignore
if (data.size > 60) {
return 'big';
}

이렇게 둘 다 ignore를 해버리게되었습니다.


이런경우, 어떤문제가 발생할까요? 저는 발생하지않을거라 생각했습니다.

null, undefined인 경우에는 무조건 if문을 통해 걸러질거기 때문에,

반드시 size프로퍼티로 접근할 수 있을거라 착각했습니다.


만약, 저 데이터가 서버에서 오는 데이터라고 했을 때,

const data = {
product_size: 123,
productSize: 456
};

위 혹은 아래처럼 size가 아니라 다른 키로 데이터를 서버에서 응답하는경우 어떻게될까요?


분명, 프론트앤드 개발자에게 미리 알려줬을겁니다. size에서 productSize로 바뀔거라구요.


네 맞습니다 저도 그걸 전달받고나서,

interface DataType {
size: number;
}

function sizeToState(data: DataType | undefined | null): '...'

이렇게 되어있던 타입을,


interface DataType {
productSize: number;
}

이렇게 바꿨거든요.


그래서 저 데이터 타입을 사용하는 다른 모든 코드는 전부

size에서 productSize라는 property로 바꾸라는 타입스크립트의 경고를 듣고 수정까지 잘 해줬습니다.


그리고 그거로 끝난줄알았습니다만..........

//@ts-ignore
if (data.size > 60) {
return 'big';
}

여기는 ignore를 했기 때문에 타입을 size에서 productSize로 바뀌는일이 발생한다하더라도 

typescript는 저에게 경고를 알려주지 않았습니다.


그리고 프로덕션레벨에서 저거때문에 버그가 발생했습니다.


#세줄요약

1. 경고를 끄면

2. 나중에 타입이 바뀌어도

3. 다시 알려주지 않는다.


다시 돌이켜보자면요,

//@ts-ignore
if (data.size > 60) {
return 'big';
}

처음에 제가 여기서 ignore를 한것은, 

"타입가드가 위에서 작동하지않으니까 경고를 무시하려고" 했습니다.


하지만 코드라는건 앞으로 얼마든지 변경할 수 있는 여지가 있기 때문에,

앞으로 영원히 다른 경고 조차도 받을 수 없게된다는 정말 큰 단점을 이번에 알게되었습니다.


분명 제가 의도한건 다른경고도 무시하려고 했던게 아니었거든요.

딱 타입가드 하나만 무시하려고했거든요.

하지만 이렇게됬습니다.


제 실수가 다른분들에게 도움되었으면 좋겠습니다.

14
3
  • 댓글 10

  • John Suhr
    3k
    2020-12-09 19:45:22

    추천을 하나밖에 못드려서 아쉽네요

  • Frudy
    6k
    2020-12-09 22:09:43

    좋게봐주셔서 감사합니다

  • ISA
    4k
    2020-12-10 23:56:17
    시행착오는 좋은 것이죠. 실패에서 배우는게 있다면 성장한거니까요. 화이팅
  • fender
    20k
    2020-12-11 06:55:59

    제가 파이썬을 싫어하는 이유도 비슷합니다. 지금하는 파이썬 프로젝트의 상황이 이렇습니다:

    ]$ find . -name "*.py" -exec cat "{}" \; | wc -l
    4380
    
    ]$ find . -name "*.py" -exec cat "{}" \; | grep "noinspection" | wc -l
    59
    
    ]$ find . -name "*.py" -exec cat "{}" \; | grep "type:ignore" | wc -l
    8

    해석하면, 겨우 4380 줄의 파이썬 코드를 작성하면서 타입 추론이 제대로 동작하지 않거나 주로 언어상의 제약으로 강제로 경고를 무시한 횟수가 무려 67회나 된다는 뜻입니다.

    말씀대로 정적 분석기의 경고를 무시하는 것은 가급적 피해야 하는 일인데, 타입스크립트는 어떤지 모르겠지만 파이썬에서 타입 정보를 활성화 해서 코딩하는 건 이래저래 짜증나는 경험인 듯 합니다. 

  • 나막신
    89
    2020-12-14 11:05:13

    일단 예제가 명확하지 않네요.

    타입스크립트 3년동안 써온 사람으로 warning을 무시할 일은 거의 없습니다. 타입 채킹은 어떤 형태로던 다 가능하고요. 

    그리고 이건 !data를 쓰면 코드가 훨씬 간결해 지고, null이나 undefined의 체킹은 data?.size로도 가능하죠. 

    if (data === null || data === undefined)
    if (!data)
  • Frudy
    6k
    2020-12-14 12:28:04
    와 그방법은 생각못했네요.

    타입스크립트 3년동안 써온 사람으로 warning을 무시할 일은 거의 없습니다
    ㅡㅡ
    거의 없다고 하셨으니 있긴있었다고 생각되는데요,
    답변자님이 생각하시는 타입체크 한계는 어떤상황이 있었나요?

    저도 이거 찾아봤었는데
    다들 타입스크립트가 타입체크하는건 한계가있으니
    tsignore를 쓸일이 가끔 있다는 뉘앙스로 설명하지,

    구체적으로 어떤 한계인지 사례는 못봤었어요.
  • ISA
    4k
    2020-12-14 12:43:35
    Anyscript에서도 문제가 될 상황이 있을까요?
  • 나막신
    89
    2020-12-14 14:48:42

    Frudy

    보통 타입스크립트라는 언어의 특성을 살펴볼 필요가 있습니다.

    가장 큰 장점은 자바스크립트에 비해 개발 중에 더 많은 에러들을 타입 체킹으로 잡아 준다는 것에 있겠죠. 

    거의라는 말 보다는 본인이 만든 코드라면 그럴 일이 없겠죠. npm package를 다운받았는데 typescript를 지원하지 않으면 모를까, 본인의 코드에 any를 허용하지 않는다면 무조건 interface나 class를 만들어야 할 꺼고요.

    그리고 이 예제는 실제 프로젝트에서는 사용하지 않는 코드일 것입니다. 

    if ([undefined, null].includes(data))

    일단 하고 싶었던 이야기는 타입스크립트는 그 기능으로 충분한 역할을 하고 있고, 한계가 있다고 보기는 힘이 듭니다. 결국 본인의 코드를 어떻게 짜느냐가 관건이겠죠.

  • ISA
    4k
    2020-12-14 16:34:23

    저는 타입스크립트 개발이 얼마 되지 않지만 ignore가 어째서 필요한지 잘모르긴 합니다. 유니온 타입이나 인터페이스를 통한 타입추론 그것도 안되면 any라는 타입이 있죠 어차피 개인이 짠 코드가 아닌 이상 @type을 지원해주고 공통 타입의 경우 root index.d.ts로 처리하는 상황에서 타입스크립트의 경고를 고의적으로 무시해야할 특수한 상황이 나오진 않나보네요

  • Frudy
    6k
    2020-12-14 21:11:01

    거의라는 말 보다는 본인이 만든 코드라면 그럴 일이 없겠죠. npm package를 다운받았는데 typescript를 지원하지 않으면 모를까, 

    ㅡㅡ


    음 그러면 본인이만든 코드라면

    타입스크립트의 한계는 없고,

    본인하기나름 이라는거군요.


    알겠습니다. 저는 includes자주쓰는데

    한계라 생각해서 ignore한적 잦거든요.

    주로 includes에서 제일많이쓴거같습니다.


    알려주셔서 감사합니다~

  • 로그인을 하시면 댓글을 등록할 수 있습니다.