위와 서드파티 라이브러리 함수의 인자 타입이 필요하다고 가정하자 (더 복잡한 인자와 타입을 가질 수도 있다)
가장 쉬운 방법으로는 아래처럼 튜플 형식으로 타입을 정의하는 것이다.
하지만 이렇게 하게 되면 SSoT 에 위배되므로 좋은 타입 설계는 아니다.
위와 같은 상황에서는 Parameters
를 사용할 수 있다.
정확하게 파라미터 타입을 가져온 것을 확인할 수 있다.
반환값에 대한 타입은 ReturnType<typeof function>
이다
위와 같이 config
의 타입을 정의한다고 가정하자. 언뜻보기엔 맞는 거 같지만 타입스크립트는 제대로 작동하지 않는다.
Color
타입에 2가지 타입이 존재하기 때문에 정확한 타입을 알기 위해선 타입 가드나 타입 좁히기를 해줘야 한다.
하지만 사실 config
객체엔 타입 정의가 되지 않아도 타입 추론에 의해 제대로 타입이 작동한다.
하지만, 타입이 없다면 필수값이 없는 상황에서 제대로된 에러를 뱉지 못하게 된다. (r, g, b는 필수값인 상황)
(필수값인 background
의 값을 빈 객체로 변경해도 타입 에러가 나오지 않는다)
그럴때에 saftsfies
를 사용한다.
satisfies
의 경우, 타입 단언과 검증을 같이 실행한다. config
객체는 여전히 타입 추론을 하고 추론된 타입과 맞는지 검증한다. 그렇기 때문에 만약 객체에서 변경사항이 일어나면 컴파일 타임에 오류를 발생시킨다.
반면 일반적인 명시적 타입은 타입 추론을 비활성화한다. 그렇기 때문에 config
객체의 실제 값이 Color
타입에 맞는지에 대한 추가적인 검증을 수행하지 않는다.
그렇다면 satisfies
를 언제 사용할까? (실무에서 써본 적이 없다)
주로 keyof typeof
패턴에서 사용할 수 있다.
위처럼 keyof typeof
를 사용하여 추론한 타입을 사용할 때, 잉여 속성 체킹을 위해 명시적 타입을 지정한다고 하자.
명시적으로 타입을 지정해버리면 제대로 된 타입 체킹은 가능하지만
keyof typeof
의 이점을 잃게 된다.
이럴 때 satisfies
사용하면 keyof typeof
을 그대로 사용하면서도 타입 체킹이 가능하다.
그렇다면 satisfies, as, variable annotation는 각각 어느 상황에서 사용해야 할까
1. satisfies vs as
빈 객체를 as
로 타입을 지정한 상황이다. 여기서 as
대신 satisfies
로 변경하게 되면 undefined 에러가 나온다.
satisfies
는 키워드에서 알 수 있듯이 모든 값을 만족해야한다. 값의 실제 타입을 추론하기 때문에 타입을 만족하지 않으면 컴파일 단계에서 에러를 뱉는다.
반대로 as
는 기본적으로 타입을 강제하는 경우다. 추가적인 타입 검증이 없기 때문에 추론도 하지 않는다. 컴파일 에러는 없지만, 런타임 에러가 발생할 수도 있다.
2. satisfies vs variable annotation
위와 같은 상황에서 variable annotation
나 as
로 타입을 지정하게 되면 타입 체킹에는 문제가 없지만 객체의 키 타입이 string
이 되어 버려 이상한 타입 추론을 하게 된다.
이럴 때 satisfies
를 사용할 수 있다.
satisfies
를 사용하게 되면 원하는 의도대로 타입을 사용하면서 타입스크립트의 언어 서비스까지 잃지 않게 된다.
참고: total typescript