-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bd7e501
commit 0092936
Showing
2 changed files
with
101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// bind 타입 분석 | ||
|
||
function sayName(this: Window | typeof user, param: string) { | ||
console.log(this.name); | ||
} | ||
|
||
const user = { name: 'wally' }; | ||
const bindingUser = sayName.bind(user); | ||
bindingUser('1'); // 'wally' | ||
|
||
// Extracts the type of the 'this' parameter of a function type, or 'unknown' if the function type has no 'this' parameter. | ||
type T = ThisParameterType<typeof sayName>; | ||
// Removes the 'this' parameter from a function type. | ||
type NoThis = OmitThisParameter<typeof sayName>; | ||
|
||
|
||
// bind 사용 예제 | ||
|
||
// #1) this를 쓰는 경우 | ||
// bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>; 가 적용 | ||
const wallyUser = { | ||
name: 'wally', | ||
sayHello(this: { name: string }) { | ||
console.log(`hi, ${this.name}`); | ||
} | ||
} | ||
|
||
const sayHello = wallyUser.sayHello; | ||
const sayHi = wallyUser.sayHello.bind({ name: 'wally-wally' }); | ||
sayHi(); // 'hi, wally-wally' | ||
|
||
// #2) this를 안 쓰는 경우 | ||
// 그 나머지 케이스들 (타입 분석이 헷갈리면 this parameter를 지우고 보면 편하다) | ||
// bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R; | ||
// bind<T, A0, A1, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1): (...args: A) => R; | ||
// bind<T, A0, A1, A2, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2): (...args: A) => R; | ||
// bind<T, A0, A1, A2, A3, A extends any[], R>(this: (this: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3, ...args: A) => R, thisArg: T, arg0: A0, arg1: A1, arg2: A2, arg3: A3): (...args: A) => R; | ||
// bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R; | ||
function addFunc(a: number, b: number, c: number, d: number, e: number, f: number) { | ||
return a + b + c + d + e + f; | ||
} | ||
|
||
// 이건 bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>; 가 적용됨 | ||
const addFunc1 = addFunc.bind(null); | ||
addFunc1(1, 2, 3, 4, 5, 6); | ||
|
||
// bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R; | ||
// thisArg가 null, arg0이 1이다. | ||
const addFunc2 = addFunc.bind(null, 1); | ||
addFunc2(2, 3, 4, 5, 6); | ||
|
||
const addFunc3 = addFunc.bind(null, 1, 2); | ||
addFunc3(3, 4, 5, 6); | ||
|
||
const addFunc4 = addFunc.bind(null, 1, 2, 3); | ||
addFunc4(4, 5, 6); | ||
|
||
const addFunc5 = addFunc.bind(null, 1, 2, 3, 4); | ||
addFunc5(5, 6); | ||
|
||
// 5개 이상일 때는 typescript의 bind 내부 타입으로 선언하지 않았다. | ||
// 실제로 코딩하다보면 함수에서 이렇게 파라미터를 많이 만들지 않는다. 그래서 대부분 많이 존재하는 케이스까지만 만든 것 같다. | ||
// 그래서 이 경우는 제일 마지막인 bind<T, AX, R>(this: (this: T, ...args: AX[]) => R, thisArg: T, ...args: AX[]): (...args: AX[]) => R; 가 적용된 것이다. | ||
// 그리고 typescript 기술적 한계로 파라미터 개수에 따라 따로따로 만들지 않고 하나로 묶을 수 있는 방법이 없다는 문제도 있다...(앞으로 개선할 것이라고 기대중) | ||
// 개선된 그 예로 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-0.html#variadic-tuple-types 에서 concat 타입을 한번 참고해보자. | ||
const addFunc6 = addFunc.bind(null, 1, 2, 3, 4, 5); | ||
addFunc6(6); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// flat 타입 분석 | ||
const originalArr1 = [1, 2, 3, [1, 2], [[1], [2]]].flat(); // [1, 2, 3, 1, 2, [1], [2]]; | ||
const originalArr2 = [1, 2, 3, [1, 2]].flat(); // [1, 2, 3, 1, 2]; | ||
const originalArr3 = [1, 2, 3, [1, 2], [[1], [2]]].flat(2); // [1, 2, 3, 1, 2, 1, 2]; | ||
|
||
type User = { | ||
name: string, | ||
age: number; | ||
} | ||
type UserType = User[1 extends number ? 'age' : 'name']; | ||
|
||
// 타입스크립트에서는 아래 처럼 값의 빼기 연산이 안된다. | ||
// flat 타입 내부에서는 depth 하나 빼기 연산을 [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20][Depth] 와 같이 했다. | ||
// 하지만 이것도 depth가 20 이상일 때는 커버가 불가능하지만 솔직히 그렇게 데이터 구조 짜는 것도 신기방기하긴 하다. | ||
// type C = 3 - 1; | ||
|
||
// originalArr3 분석 | ||
// FlatArray<(number[] | number[][] | number[][][]), 2>[] | ||
// FlatArray<(number | number[] | number[][]), 1>[] | ||
// FlatArray<(number | number[]), 0>[] -> 사실 정확히는 FlatArray<(number | number | number[]), 0>[] 인데 number | number 부분은 어차피 같은 number이다. | ||
// FlatArray<number, -1>[] | ||
// number[] | ||
|
||
// flat<A, D extends number = 1>( | ||
// this: A, | ||
// depth?: D | ||
// ): FlatArray<A, D>[] | ||
|
||
// 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"]; |