우선 TypeScript의 타입 시스템에 대해 이야기하는게 좋겠다.
- Soundness의 반대개념인 Unsoundness가 런타임에 문제를 유발할 수 있지만 TypeScript는 일부 불건전한 동작을 허용한다.
Soundness
- 컴파일 타임에 알기 어려운 특정 타입을 안전하게 허용하는 것을 의미한다.
- 즉 컴파일러가 런타임 시점 값의 타입을 보장할 수 있다는 개념
- 모든 JavaScript 코드를 지원하기 위함
- 타입스크립트는 변환된 코드가 런타임에 영향을 미치지 않는 것을 목표로 한다.
일부 불건전한 코드에는 any도 있을 수 있고, as도 있을 수 있겠다.
Type Assertion에 대한 이야기를 해보자.
Type Assertion
- 타입 단언
- 타입 추론에는 어쩔 수 없는 한계가 존재하기 때문에
사용자가 타입을 가장 잘 알고 있다는 것을 명시하는 방법
const num = "1000" as unknown as number;const cat = {
name: "moo",
age: 10,
} as const;
-
객체의 모든 프로퍼티들이 readonly로 변경된다.
-
각 프로퍼티의 타입이 할당된 리터럴 값으로 추론된다.
-
값의 재할당을 막는다.
-
추론 범위를 좁혀준다.
-> 의도치 않은 오류를 없앨 수 있다. -
하지만 타입캐스팅과는 다르다!
-
타입 단언은 컴파일단에서만 타입을 변경한다. 런타임에 영향을 주지 않는다.
-
어쩔 수 없는 경우를 제외하고 as를 떡칠하는 경우는
any를 쓰는 것과 같다. (any를 떡칠할거면 TypeScript를 쓰지 않는게 더 낫겠지..)
내가 어떨때 as를 썼더라..🧐
- ref 달아서 이벤트핸들러 만들때 자주 쓰게 되었던 것 같다.
- DOM api 조작시에도 많이 사용했던 것 같고?
const div = document.querySelector("div") as HTMLDivElement;그렇다면 최대한 쓰지 않으려면 어떻게 해야할까?
- as를 쓰기 전에 TypeScript가 내 코드를 왜 추론하지 못하는지 살펴보자.
- 타입가드를 이용해 최대한 타입을 좁혀주자.
instanceof나new.target을 통해 타입가드를 해준다.