1. typeof type guards
typeof operator를 사용하여 narrowing(좁히기) 가능.
function printAll(strs: string | string[]) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
} else {
// do nothing
}
}
자바스크립트에서 typeof null === "object" 는 true이다.
2. truthiness narrowing
0, NaN, "", 0n, null, undefined를 체크할 수 있다.
function truthiness(target: unknown) {
return target ? true : false;
}
// all false
truthiness(0);
truthiness(NaN);
truthiness("");
truthiness(0n);
truthiness(null);
truthiness(undefined);
주의할 점은, ""와 0을 false로 체크하기 때문에 주의해야한다.
3. Equality narrowing
아래 예제처럼, 타입이 string일 때만 true절을 탈 수 있으므로, true 절 안에서 x, y는 string이라고 타입스크립트가 체크해 줄 수 있다.
function example(x: string | number, y: string | boolean) {
if (x === y) {
x // string
} else {
x // string | number
y // string | boolean
}
}
4. The in operator narrowing
in 오퍼레이터를 사용해서 체크할 수 있다.
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
return animal.swim(); // animal is Fish
}
return animal.fly(); // animal is Bird
}
5. instanceof narrowing
function logValue(x: Date | string) {
if (x instanceof Date) {
console.log(x.toUTCString()); // x is Date
} else {
console.log(x.toUpperCase()); // x is string
}
}
6. Assignments
값을 할당할 때, 타입스크립트는 적절하게 추론하여 타입을 매긴다. x변수는 string | number 타입을 가질 수 있다고 할당했다. 그러나 다른 타입이 들어오면 error를 나타낸다.
let x = Math.random() < 0.5 ? 10 : "hello world!"; // x: string | number
x = 1; // x: number
x = "goodbye!"; // x: string
x = true // ❌Error: Type 'boolean' is not assignable to type 'string | number'.
7. Control flow analysis
조건문을 통과하는 흐름을 분석해서, 타입을 유추한다.
function example() {
let x: string | number | boolean;
x = Math.random() < 0.5;
console.log(x); // x: boolean
if (Math.random() < 0.5) {
x = "hello";
console.log(x); // x: string
} else {
x = 100;
console.log(x); // x: number
}
return x; // x: string | number
}
8. Using type predicates
type Fish = { swim: () => void };
type Bird = { fly: () => void };
type Pet = Fish | Bird;
function isFish(pet: Pet): pet is Fish {
return (pet ad Fish).swim !== undefined;
}
const zoo: Pet[] = [...pets];
const underWater1: Fish[] = zoo.filter(isFish);
const underWater2: Fish[] = zoo.filter((pet): pet is Fish => {
if (pet.name === "sharkey") return false;
return isFish(pet);
});
9. Discriminated unions
interface Circle {
kind: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.sideLength ** 2;
}
}
10. The never type
좁힐 때, 모든 가능한 타입을 없애면, 타입스크립트는 never 타입을 사용한다.
11. Exhaustiveness checking
type Shape = Circle | Square;
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.sideLength ** 2;
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
'front > ts' 카테고리의 다른 글
[타입스크립트] 프로퍼티를 조작할 때 주석을 유지하기 (0) | 2022.07.20 |
---|---|
[타입스크립트] 타입의 모든 프로퍼티를 Optional로 바꾸는 타입 (0) | 2022.07.19 |
[The Basics] Erased Types (0) | 2022.05.16 |
[The Basics] Explicit Types (0) | 2022.05.16 |
[The Basics] Emitting with Errors (0) | 2022.05.16 |
댓글