InflearnTS Chapter 28~32 - YDP-SPLOUNGE-CLUB/typescript-study GitHub Wiki
๋ง์ฝ ๋ฐ์ ์๋ Profile ๊ฐ์ด ๋ชจ๋ ์์ฑ์ด ์ต์ ๋์ธ ์ธํฐํ์ด์ค์์ ๋ชจ๋ ์์ฑ์ ํ์๋ก ๋ฐ๊พธ๊ธฐ ์ํด์๋ ์ด๋ป๊ฒ ํด์ผํ ๊น?
interface Profile {
name?: string,
age?: number,
married?: boolean,
}
const zeroCho: Required<Profile> = {
name: 'zero',
age: 29,
married: false,
}
// ์ง์ Requried ๋ฅผ ๊ตฌํํด๋ณด์.
type R<T> = {
[Key in keyof T]-?: T[Key];
}
const zeroCho2: R<Profile> = {
name: 'zero',
age: 29,
married: false,
}Readonly ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ชจ๋ ์์ฑ์ readonly ๋ฅผ ๋ถ์ฌ์ ๋ง๋ค๊ฑฐ๋ Readonly ์ - ๋ฅผ ๋ถ์ฌ ์์จ ์ ์๋ค.
interface Profile {
name?: string,
age?: number,
married?: boolean,
}
type R<T> = {
-readonly [Key in keyof T]: T[Key];
}Record ๋ ๋ฐ์ ์ฝ๋๋ฅผ ๊ฐ๋จํ ๋ฐ๊พผ ์ฝ๋์ด๋ค.
interface Obj {
[key: string]: number;
};
// ๋์ผ
const a: Record<string, number> = {a: 3}
// Record ๋ฅผ ์ง์ ๋ง๋ค์ด๋ณด์.
type R<T extends keyof any, S> = {
[Key in T]: S;
}NonNullable ์ Null ์ด๋ undefined ๋ฅผ ์ ์ธํ๊ณ ๋ถ๋ฌ์ฌ ์ ์๋ค.
type A = string | null | undefined | boolean | number;
type B = NonNullable<A>; // string boolean number;
// ์ง์ ๋ง๋ค์ด๋ณด์
type N<T> = T extends null | undefined ? never: T;function zip(x: number, y: string, z: boolean): {
x: number,
y: string,
z: boolean
} {
return { x, y, z };
}
// zip ์ ํ๋ผ๋ฏธํฐ๋ค์๊ฒ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
type Params = Parameters<typeof zip>;
// ๋ํ Parmas ๋ ๋ฆฌ์คํธํ์ด๊ธฐ ๋๋ฌธ์ [0] x: number ์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
type First = Params[0];Parameter ๋ฅผ ์ง์ ๋ง๋ค์ด๋ณด์.
function zip(x: number, y: string, z: boolean): {
x: number,
y: string,
z: boolean
} {
return { x, y, z };
}
// infer ๋ ์ถ๋ก ์ด๋ ๋ป์ด๋ค.
// Paramemter ๋ฅผ ์๋ฏธํ๋ P ํจ์๋ infer A [parameter] ๋ฅผ ์ถ๋ก ํ๋ค.
type P<T extends (...args: any) => any> = T extends (...args: infer A) => any ? A : never;
// ReturnType ๋ฅผ ์๋ฏธํ๋ R ํจ์๋ infer A [returns ์ถ๋ ฅ๊ฐ] ๋ฅผ ์ถ๋ก ํ๋ค.
type R<T extends (...args: any) => any> = T extends (...args: any) => infer A ? A : never;
type Params = P<typeof zip>;
// ๋ค์๊ณผ ๊ฐ๋ค.
// [x: number, y: string, z: boolean]
type Returns = R<typeof zip>;
// ๋ค์๊ณผ ๊ฐ๋ค.
// type Returns = {
// x: number;
// y: string;
// z: boolean;
// }๋ ๋ค๋ฅธ ์
class A {
a: string;
b: number;
c: boolean;
constructor(a: string, b: number, c: boolean) {
this.a = a;
this.b = b;
this.c = c;
}
}
const c = new A('123', 345, true);
// ConstructorParameter ๋ฅผ infer ๋ก ์ถ๋ก ํ์ฌ ๊ฐ์ ธ์จ๋ค.
type C = ConstructorParameters<typeof A>;
// ๋ค์๊ณผ ๊ฐ๋ค. [a: string, b: number, c: boolean]
// Instance ์์ฒด๋ฅผ ์ถ๋ก ํด์ ๊ฐ์ ธ์จ๋ค.
type I = InstanceType<typeof A>;
// ๋ค์๊ณผ ๊ฐ๋ค. A
type C2<T extends abstract new (...args: any) => any> =
T extends abstract new (...args: infer P) => any ? P : never;
type I2<T extends abstract new (...args :any) => any> =
T extends abstract new (...args: any) => infer I ? I : never;๋ ์ด๋ ค์ด ์์ ๋ฅผ ์ฐพ์์๋ค..
const p1 = Promise.resolve(1).then((a) => a + 1).then((a) => a + 1).then((a) => a.toString());
const p2 = Promise.resolve(2);
const p3 = new Promise((res, rej) => {
setTimeout(res, 1000);
});
Promise.all([p1, p2, p3]).then((result) => {
console.log(result); // ํ์
์ถ๋ก [string, number, unknown]
});all ์ ๋ํ ํ์ ์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
all<T extends readonly unknown[] | []>(values: T): Promise<{-readonly [P in keyof T]: Awaited<T[P]>}>;ํด์ ์์
- Promise.all ์์ ์๋ ๊ฐ์ฒด๋ค์ readonly ๋ก ์ฝ์ด๋ค์ธ๋ค.
- Promise ํด์์ด ๋๋ ์ํ์์๋ readonly ๋ฅผ ์ญ์ ์์ผ ์์ ๋ก์ด ์ํ๋ก ๋ณํ์์ผ ์ค๋ค.
- Awaited ๋ผ๋ ํ์ ๋ด์์ then ์ ๊ฐ์ Return ์์ผ์ค๋ค.
Awaited ๋ผ๋ ํจ์์์ ์ด๋ค ์ผ์ด ์ผ์ด๋ฌ๋๊ฐ?
type Awaited<T> =
T extends null | undefined ? T : // special case for `null | undefined` when not in `--strictNullChecks` mode
T extends object & { then(onfulfilled: infer F): any } ? // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
F extends ((value: infer V, ...args: any) => any) ? // if the argument to `then` is callable, extracts the first argument
Awaited<V> : // recursively unwrap the value
never : // the argument to `then` was not callable
T; // non-object or non-thenablep1 ์ ์์๋ก ์์ฐจ์ ์ผ๋ก ํด์ํด๋ณด๋ฉด
- T๊ฐ null ๋๋ undefined ์ธ๊ฐ? false ์ด๋ฏ๋ก T ๊ฐ์ ๋ด๋ณด๋ด์ง ์๊ณ ๋ค์ ํ์ ์ ํด์ํ๋ค.
- T extends object & { then(onfulfilled: infer F): any } <- ๋ํ์ดํ ์ ํตํด์ then ์ด ์๋ ํจ์์ธ์ง๋ฅผ ํ๋ณ
- F ๊ฐ true ๋ผ๋ฉด Awaited ๋ฅผ ํตํด์ ๋ค์ํ๋ฒ ์ฌ๊ทํจ์๋ฅผ ์คํ์ํค๋ฉฐ
- F ๋ผ๋ ํจ์๊ฐ extends ๋ฅผ ๋ง์กฑ์ํค์ง ์๋ ํจ์๋ผ๋ฉด ํจ์์ ์๋ฌด๋ฐ ๊ฐ์ ๋ด๋ณด๋ด์ง ์๋๋ค.
- T extends object & { then(onfulfilled: infer F): any } ๊ฐ ์๋๋ผ๋ฉด T ๋ฒจ๋ฅ ์์ฒด๋ฅผ ๋ด๋ณด๋ธ๋ค.
- p1 ์ ์ฒซ ๊ฐ์ number.then(...) ์ด๋ฏ๋ก then(onfulfilled: inter F): any ์ ์ ํฉํ๋ฏ๋ก
- F extends ((value: infer V, ...args: any) => any) ? (a + 1) ๋ฅผ ์ฝ์ด๋ค์ด๋ฉฐ Awaited ์ฌ๊ท๋ฅผ ๋ฐ์์ํจ๋ค.
- ์ฌ๊ท๋ฅผ ๋ฐ๋ณตํ๋ฉฐ ๋ง์ง๋ง v.toString() ๊น์ง ๋๋ฌํ์๊ณ ๋ค์ ์ถ๊ฐ์ ์ผ๋ก ๋ถ๋ then ์ด ์์ผ๋ฏ๋ก T extends object & { then(onfulfilled: infer F): any } ์กฐ๊ฑด์ ๋ถ๋ง์กฑํ๋ค.
- T ๋ผ๋ ๊ฐ์ ๋ด๋ณด๋ด๋ฉฐ p1 ์ resolve ๊ฐ์ string ์ด ๋๋ค.
const a = [1,2,3, [1,2], [[1], [2]]].flat(); // (number| number[])[]
const a2 = [1,2,3, [1,2], [[1], [2]]].flat(2); // number[]FlatArray ์ ๊ดํ ํ์ ์ ๋ค์๊ณผ ๊ฐ๋ค.
type FlatArray<Arr, Depth extends number> = {
"done": Arr,
"recur": Arr extends ReadonlyArray<infer InnerArr>
? FlatArray<InnerArr, [-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20][Depth]>
: Arr
}[Depth extends -1 ? "done": "recur"];์ฝ๊ฒ ์ค๋ช ํ๋ฉด depth ๊ฐ ๋๋ฌ๋ค๋ฉด done ์ ํธ์ถํ์ฌ ๋ฐฐ์ด ๊ทธ๋๋ก๋ฅผ ๋ฐํํ๋ฉฐ ์๋๋ผ๋ฉด Arr ์ Depth ๋ฅผ ํ์ด์ค์ ์ฌ๊ทํจ์๋ฅผ ํธ์ถํ๋ค.
๋ง์ฝ flat(1) ์ด๋ผ๋ฉด -> 0 ์ ํธ์ถํ๊ณ flat(0) ์ ํธ์ถํ๊ณ ๊ทธ ์ดํ -1 ์ ํธ์ถํ์ฌ "done" ์ ๋ฐํํ๊ฒ ๋๋ค.
20์ฐจ์์ ๋ฆฌ์คํธ๋ฅผ ๊ณ ๋ คํด์คฌ์ง๋ง 25์ฐจ์ ์ฏค ๋๋ฉด ํ์ ์คํฌ๋ฆฝํธ๊ฐ ์ดํด๋ฅผ ๋ชปํ๋ค.
๋ค์ ๋์๊ฐ์
// ํด๋น ํจ์์์ infer InnerArr ๋ ๋ฆฌ์คํธ ์์ชฝ์ ์๋ ๋ฐฐ์ด๋ค์ด๋ค.
// infer InnerArr = number, number[], number[][]
const a = [1,2,3, [1,2], [[1], [2]]].flat(2);์์ฐจ์ ์ผ๋ก ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- FlatArray<(number[] | number[][] | number[][][]), 2>[] ์ํ์์ FlatArray ๋ฅผ ํธ์ถ FlatArray Depth ๊ฐ 2 ์ด๋ฏ๋ก ReadOnlyArray number[] | number[][] | number[][][] ์ ์์ชฝ ๋ฐฐ์ด์ ์ฝ์ด ํ ์ฐจ์ ๋ฐ์ผ๋ก ๋ด๋ฆฐ๋ค. ๋ํ FlayArray<InnerArray, -1,0,1,2,...[2] = 1 ๋ฅผ ๋ถ๋ฌ๋ด์ ์ฌ๊ท ํจ์๋ฅผ ์คํ
- FlatArray<(number | number[] | number[][]), 1>[] ๋ฐ๋ณต
- FlatArray<(number | number[]), 0>[] ๋ฐ๋ณต
- FlatArray<number, -1>[] -1 ์ด๋ฏ๋ก Arr ์์ฒด๋ฅผ ๋ฐํ
- number []