타입스크립트를 사용하다보면 아래와 같은 상황을 자주 볼 수 있다.
const foo = useQueryParams("foo") // {title: string} | undefined
return (
<div> {foo.title} </div> // Error: undefined일 수 있음
)
그리고 다음 방법 중 하나를 사용하곤 한다.
const foo = useQueryParams("foo") // {title: string} | undefined
/* 1. Early Return 사용 */
if (!foo) {
return null
}
/* 2. Optional Chaining 사용 */
return (
<div> {foo?.title} </div>
)
하지만 사용하는 페이지에서 무조건 foo가 있다는 것을 확신할 수 있다면 (없으면 페이지 진입 자체가 안되는 경우)
더 좋은 방법이 있지 않을까?
Assert signature
타입스크립트에 assert signature라는 것이 있다.
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg)
}
}
const foo = useQueryParams("foo")
assert(!foo, foo가 없습니다)
return (
<div> {foo.title} </div>
)
asserts는 함수에서 에러가 발생하지 않으면, conditon이 참임을 타입스크립트에 알려준다.
따라서 foo.title이 undefined가 아님을 알려주고, {title: string} 타입으로 narrowing된다.
응용
파라미터의 타입을 확인하지 않고, 타입스크립트에 특정 타입을 알려줄 수 있다.
function assertIsString(val: any): asserts val is string {
if (typeof val !== "string") {
throw new Error("Not a string!");
}
}
assertIsString 함수에서 에러가 발생하지 않으면, 타입스크립트는 val의 타입을 string로 내로잉한다.
function test(str: any) {
assertIsString(str);
// 타입스크립트는 'str'이 'string'임을 알고 있다.
return str.toUppercase();
// ~~~~~~~~~~~
// error: Property 'toUppercase' does not exist on type 'string'.
// Did you mean 'toUpperCase'?
}
이는 is에서 사용했던 방식과 매우 유사하다
Reference
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#assertion-functions
'Web > TypeScript' 카테고리의 다른 글
TypeScript - is keyword (0) | 2024.05.29 |
---|---|
TypeScript 공식 라이브러리 tslib란 무엇인가 (3) | 2024.01.10 |
모노레포에서 Typescript 사용중 발생한 vscode 에러 (0) | 2023.08.20 |