타입 단언

김동현·2022년 5월 17일
0

TypeScript

목록 보기
13/18
post-thumbnail

StrictNullChecks 옵션

false로 설정하는 경우

tsconfig.js에서 strictNullChecks 옵션이 false인 경우 null과 undefined는 never을 제외한 나머지 타입에 대한 서브 타입이 됩니다.

포함 관계 : 모든 타입 > "null", "undefined" > any

즉, 모든 타입들은 null과 undefined를 서브 타입으로 허용하게 됩니다.

true로 설정하는 경우

strictNullChecks 옵션을 true로 설정한 경우 null의 하위 타입은 없으며, undefined 타입의 하위 타입도 존재하지 않게 됩니다.

포함 관계 : unknown, any > void > "undefined" > any
포함 관계 : unknown, any > "null" > any

즉, null 타입은 null 값만을 가질 수 있고, undefined 타입은 undefined 값만을 가질 수 있습니다.


null과 undefined에 대해 엄격한 타입 체킹을 제공하게 됩니다.

이는 null이나 undefined 값을 가질 수 있는 경우에 대해서도 타입스크립트 컴파일러가 null과 undefined도 고려 대상에 포함하게 됩니다.

위 코드는 strictNullChecks가 false인 경우이며, rootNode에 HTMLElement 타입으로 추론되는 것을 확인할 수 있습니다.

반면 true로 설정한 경우에는 아래와 같이 타입이 추론됩니다.

이는 getElementById로 노드 객체를 찾지 못한 경우를 포함하여 반환값이 설정되어 있습니다.

타입스크립트 컴파일러는 HTML 문서를 확인하지 못하므로 노드 객체 취득할 수 있을지 없을지 알 수 없기 때문에 null 타입을 유니온 타입으로 갖도록 설정되어 있습니다.

타입 단언

strictNullChecks 옵션을 true로 설정하여 위와 같은 상황이 발생한 경우 타입스크립트 컴파일러보다 개발자가 타입에 대한 정보를 정확히 알고 있는 경우 타입 단언을 하여 타입을 강제할 수 있습니다.

일반적으로 타입스크립트의 타입은 변경되지 않지만 타입 단언을 사용하는 경우에는 타입을 변경할 수 있습니다.

1. "<type>" 으로 타입 단언하기

"<type>표현식" 형태로 해당 표현식에 대한 타입을 단언할 수 있습니다.

위 코드처럼 표현식 가장 앞에 <type>을 작성해주는 방식으로 타입스크립트에게 특정 타입으로 인지되도록 할 수 있습니다.

2. "as type"으로 타입 단언하기

"표현식 as type" 형식으로 표현식에 대한 타입을 단언할 수 있습니다.

두 방법중 어떤 방법을 사용하더라도 문제가 되지 않지만 한 가지 방법으로 통일하여 사용하는 것을 권장합니다.

3. "as const"로 타입 단언하기

"표현식 as const" 형식으로 작성하는 경우에는 표현식의 타입을 아래 그림처럼 단언하게 됩니다.

  • let 키워드로 선언한 변수에 원시값 할당시, const 키워드로 선언한 것처럼 리터럴 타입으로 타입이 단언됩니다.

  • 객체의 프로퍼티에 as const 작성한 경우 프로퍼티 값 타입은 const 키워드로 선언한 변수처럼 타입이 단언됩니다.

  • 객체 자체에 as const 작성한 경우 모든 프로퍼티가 readonly 프로퍼티가 되고, 프로퍼티 값의 타입은 const 키워드로 선언한 변수처럼 타입이 단언됩니다.

  • 배열에 as const 작성한 경우 readonly 배열 타입으로 단언됩니다.
    readonly 튜플은 튜플 타입과 유사하며 추가적으로 요소값을 수정할 수도 없게 됩니다.

4. "!" 타입 단언하기

표현식 마지막에 !을 붙여준다면 해당 표현식을 null 값을 갖지 않는다고 타입스크립트에게 알려주는 역할을 합니다.

위 코드처럼 마지막에 !을 작성함으로써 더이상 HTMLElement | null이 아닌 HTMLElement만을 갖는다고 타입스크립트에게 인지시켜 줍니다.


참고로 위에서 살펴본 타입 단언과 !을 같이 사용할 수도 있습니다.


!는 우리가 해당 표현식이 null을 반환하지 않을 것을 안다면 작성해줍니다. 만약 null을 반환하지 않는다고 확신하지 못한다면 if문을 사용해줍니다.

이때 위에서 살펴본 형 변환을 통해 HTMLElement가 아닌 HTMLInputElement 타입으로 형 변환하는 작업이 필요합니다. 그렇지 않으면 HTMLElement 타입을 갖는다고 인식되므로 HTMLInputElement에 존재하는 특정 프로퍼티에 대한 접근에 에러가 발생하게 됩니다.

❗️주의할 점

타입 단언의 경우 현재 타입에서 상위 혹은 서브 타입으로만 타입 단언이 가능합니다.

즉, 타입 단언문으로 아예 포함관계가 없는 임의의 타입 간에 변환하는 것은 불가능합니다.

위 코드처럼 Book 인터페이스와 Person 인터페이스는 서로 상위나 하위 타입의 관계를 갖지 않기 때문에 변환이 불가능합니다.

임의의 타입으로 변경하는 것을 우회하여 사용할 수는 있습니다.
as unknown as type 처럼 단언을 사용한다면 임의의 타입으로 변경이 가능합니다.

profile
Frontend Dev

0개의 댓글