Narrowing
- Narrowing은 Union 타입에서 더욱 구체적인 타입으로 논리적으로 유추 할 수 있게 되는 걸 의미한다.
Narrowing 종류
- Assignment Narrowing
- typeof Narrowing
- Truthiness Narrowing
- Equality Narrowing
- in operator Narrowing
- instanceof Narrowing
- discriminated union Narrowing(차별된 유니언 내로잉)
- exhaustiveness checking
1. Assignment Narrowing
let numberOrString: number | string = "string";
numberOrString.toString();
2. typeof Narrowing
numberOrString = Math.random() > 0.5 ? 1123 : "string";
if (typeof numberOrString === "string") {
numberOrString.toString();
} else {
numberOrString.toFixed(2);
}
3. Truthiness Narrowing
let nullOrString: null | string[] = Math.random() > 0.5 ? null : ["string"];
if (nullOrString) {
nullOrString.toString();
} else {
nullOrString;
}
4. Equality Narrowing
let numberOrString2: number | string = Math.random() > 0.5 ? 1123 : "string";
let stringOrBool2: string | boolean = Math.random() > 0.5 ? "string2" : true;
if (numberOrString2 === stringOrBool2) {
numberOrString2;
stringOrBool2;
} else {
numberOrString2;
stringOrBool2;
}
let numberOrStringOrNull: number | string | null =
Math.random() > 0.5 ? 1123 : Math.random() > 0.5 ? "string" : null;
if (typeof numberOrStringOrNull === "number") {
numberOrStringOrNull;
} else {
numberOrStringOrNull;
}
5. in operator Narrowing
interface Human {
name: string;
age: number;
}
interface Dog {
name: string;
type: number;
}
let human: Human = {
name: "4.21ee",
age: 33,
};
let dog: Dog = {
name: "초코",
type: 1,
};
let humanOrDog: Human | Dog = Math.random() > 0.5 ? human : dog;
if ("type" in humanOrDog) {
humanOrDog;
} else {
humanOrDog;
}
6. instanceof Narrowing
let dateOrString: Date | string = Math.random() > 0.5 ? new Date() : "string";
if (dateOrString instanceof Date) {
dateOrString;
} else {
dateOrString;
}
7. discriminated union Narrowing(차별된 유니언 내로잉)
interface Animal {
type: "dog" | "human";
height?: number;
breed?: string;
}
let animal: Animal =
Math.random() > 0.5
? { type: "human", height: 170 }
: { type: "dog", breed: "poodle" };
if (animal.type === "human") {
animal.height;
} else {
animal.breed;
animal.height;
}
interface Human2 {
type: "human";
height: number;
}
interface Dog2 {
type: "dog";
breed: string;
}
interface Fish2 {
type: "fish";
swimSpeed: number;
}
type HumanOrDog2 = Human2 | Dog2 | Fish2;
let humanOrDog2: HumanOrDog2 =
Math.random() > 0.5
? { type: "human", height: 170 }
:
Math.random() > 0.5
? {
type: "dog",
breed: "poodle",
}
: {
type: "fish",
swimSpeed: 100,
};
if (humanOrDog2.type === "human") {
humanOrDog2;
} else {
humanOrDog2;
}
8. exhaustiveness checking
switch (humanOrDog2.type) {
case "human":
humanOrDog2;
break;
case "dog":
humanOrDog2;
break;
case "fish":
humanOrDog2;
break;
default:
humanOrDog2;
const _check: never = humanOrDog2;
break;
}