타입 좁히기
여러 가지일 수 있는 값을 확인해서 하나로 좁힙니다.
확인하면 그만큼 좁아집니다
1.4 에서 유니온을 받으면 모두가 가진 것만 사용할 수 있다는 것을 보았습니다. 그러면 어느 쪽인지 확인하면 됩니다.
TypeScript 는 확인하는 코드를 읽고 그 안쪽에서 타입을 좁힙니다. 따로
알려 주지 않아도 if 를 보고 알아냅니다.
if (typeof value === "string") { // 여기서 value 는 string 입니다 } else { // 여기서는 나머지입니다 }
typeof 로 좁히기
function show(value: string | number): string { if (typeof value === "string") return value.toUpperCase(); return value.toFixed(1); } console.log(show("a-1")); console.log(show(3));
return 뒤에는 else 를
적지 않았는데도 value.toFixed 가 됩니다.
글자인 경우는 이미 돌아갔으니 남은 것은 숫자뿐이라는 것을 압니다.
값으로 갈라지는 유니온
리터럴 유니온(1.4)은 값을 견주어 좁힙니다.
switch 와 잘 맞습니다.
type Status = "pending" | "done" | "failed"; function label(status: Status): string { switch (status) { case "pending": return "기다리는 중"; case "done": return "끝났습니다"; case "failed": return "실패했습니다"; } } console.log(label("pending")); console.log(label("failed"));
default 가 없는데도 오류가 나지 않았습니다.
세 가지를 모두 다뤘으니 빠진 경우가 없다는 것을 압니다. 그래서
Status 에 값을 하나 더하면 이 함수가 곧바로
오류가 되어, 고칠 자리를 알려 줍니다.
객체를 갈라내는 표시
객체가 여러 모양일 때는 모양마다 다른 값을 담는 속성을 하나 두고 그것으로
갈라냅니다. 자주 kind 나
type 이라고 이름 붙입니다.
type Circle = { kind: "circle"; radius: number }; type Rect = { kind: "rect"; width: number; height: number }; function area(shape: Circle | Rect): number { if (shape.kind === "circle") return Math.round(shape.radius * shape.radius * 3.14); return shape.width * shape.height; } console.log(area({ kind: "circle", radius: 10 })); console.log(area({ kind: "rect", width: 3, height: 4 }));
shape.kind 를 견주는 것만으로
radius 와 width 를 각각
사용할 수 있게 됩니다. 서버가 돌려주는 응답이 경우마다 다를 때 이 방식을
자주 사용합니다.
type Circle = { kind: "circle"; radius: number }; type Rect = { kind: "rect"; width: number; height: number }; function area(shape: Circle | Rect): number { return shape.width * shape.height; }
좁히지 않으면 이렇게 막힙니다. 딸린 설명이 왜 없는지 짚어 줍니다 —
Circle 에 width 가
없기 때문입니다.
처음에 자주 걸리는 것
JavaScript 의 오래된 규칙이 그대로 있습니다(JS 1.4).
typeof x === "object" 로 좁힐 때는
x !== null 을 함께 확인해야 합니다.
배열도 "object" 입니다.
Array.isArray(x) 를 사용합니다 — 이것도 좁혀 줍니다.
if (isString(value)) 처럼 직접 만든 함수로
확인하면 그 안쪽에서 좁혀지지 않습니다. 좁혀 주게 하려면 반환 타입을
value is string 으로 적어야 합니다.
직접 해보기
글자·숫자·참거짓을 받아 각각 다르게 설명하는 함수를 만드세요.
function describe(value: string | number | boolean): string {
if (typeof value === "string") return `글자 ${value}`;
if (typeof value === "number") return `숫자 ${value}`;
return `참거짓 ${value}`;
}
console.log(describe("홍길동"));
console.log(describe(27));
console.log(describe(true));
위 area 에 삼각형을 더하고, 더하는 순간 어디가
오류로 잡히는지 확인하세요.
type Triangle = { kind: "triangle"; base: number; height: number } 를 만들고 매개 변수 타입에 이어 붙입니다. 마지막 return shape.width * shape.height 가 곧바로 막히므로 고쳐야 할 자리를 컴파일러가 알려 줍니다. 이것이 갈라내는 표시를 두는 값입니다.이 단원의 정리
- 확인하는 코드를 읽고 그 안쪽에서 타입이 좁아집니다.
typeof로 기본 타입을 갈라냅니다.- 리터럴 유니온은 값을 견주어 갈라냅니다.
- 객체는 갈라내는 표시 속성을 하나 두고 그것으로 갈라냅니다.
- 모든 경우를 다루면
default가 없어도 됩니다.