function printAll(strs: string | string[] | null) {
// BAD ๐ฉ
// Null check๋ฅผ ์ ์ด๋ ๊ฒ ์ฐ๋ฉด ์๋๋? ๋น ๋ฌธ์์ด์ธ ๊ฒฝ์ฐ๋ฅผ ๋ฌด์ํ๊ธฐ ๋๋ฌธ (string ''์ธ ๊ฒฝ์ฐ)
if (strs) {
if (typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
}
}
// GOOD ๐
if (strs && typeof strs === "object") {
for (const s of strs) {
console.log(s);
}
} else if (typeof strs === "string") {
console.log(strs);
}
}
== null
์ null๊ณผ undefined๋ฅผ ๋ชจ๋ ์ฒดํฌํ๋ค. (== undefined
๋ ๋ง์ฐฌ๊ฐ์ง) (=== ์๋ ๊ตฌ๋ถ๋จ)in
๊ฐ์ฒด ์์ฑ์ด ๋ค์ด์๋์ง ์๋์ง ์ฌ๋ถ๋ก type narrowing์ด ๊ฐ๋ฅํ๋ค.type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
return animal.swim();
}
return animal.fly();
}
if (x instanceof Date)
)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:
// ์ด๋ฐ shape์ circle์ square์ ์ํ ํ์
๊ฐ๋๊ฐ ์ง์ ๋์๊ธฐ ๋๋ฌธ์,
// ๋ ์ด์ ์ฌ์ ์๋ ํ์
์ด ์์ด never ํ์
์ด๋๋ค.
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
function fail(msg: string): never {
throw new Error(msg);
}
function longest<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a;
} else {
return b;
}
}
// longerArray is of type 'number[]'
const longerArray = longest([1, 2], [1, 2, 3]);
// longerString is of type 'string'
const longerString = longest("alice", "bob");
// Error! Numbers don't have a 'length' property
const notOK = longest(10, 100); // ์ซ์๋ length ์์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ์๋ฌ
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
arr1.push(...arr2); // arr1.push(1,2,3)๊ณผ ๊ฐ์
type ColorfulCircle = Colorful & Circle;
- Intersection Types (&)
(Colorful๊ณผ Circle์ interface. (์ฉ์ด๋ฅผ ๋ชฐ๋์ด์ ์ ์))
๋ณ๊ฒฝ๋๋ฉด ์๋๋ ๋ฐฐ์ด์ธ ๊ฒฝ์ฐ ReadonlyArray ์ ๋๋ฆญ ํ์ ์ ์ฌ์ฉํ๋ค.
// ํฉํ ๋ฆฌ ํจํด์์ ์์ฑ์๊ฐ createํจ์๋ก ๋๊ฒจ์ง๋ ๊ฒ ํ์ดํ
function create<Type>(c: { new (): Type }): Type {
return new c();
}
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};
// ๋ชจ๋ ์์ฑ์ด optionalํ์ง ์๊ฒ ๋จ
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};
// Type์ key๊ฐ name, age, location์ด๋ผ๋ฉด
// Getters ํ์
์ key๋ค์ getName, getAge, getLocation์ด ๋๋ค.