평부 2022. 9. 20. 15:34

 

출처 : https://github.com/ZeroCho/ts-all-in-one

 

GitHub - ZeroCho/ts-all-in-one

Contribute to ZeroCho/ts-all-in-one development by creating an account on GitHub.

github.com

 

 

출처 : https://github.com/microsoft/TypeScript/blob/main/lib/lib.es5.d.ts

 

GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

TypeScript is a superset of JavaScript that compiles to clean JavaScript output. - GitHub - microsoft/TypeScript: TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

github.com

 

 

 

*  [lib.ex5.d.ts] bind & ThisParameterType, OmitThisParameter

//bind
bind<T>(this: T, thisArg: ThisParameterType<T>): OmitThisParameter<T>;
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;

//ThisParameterType & OmitThisParameter
type ThisParameterType<T> = T extends (this: infer U, ...args: never) => any ? U : unknown;
type OmitThisParameter<T> = unknown extends ThisParameterType<T> ? T : T extends (...args: 

//OmitThisParameter : 타입추론이 실패했을 때 그 함수 그대로 가져옴, 타입추론 성공 시 매개변수와 리턴값 그대로 함수로 만듦(this가 사라짐)

 

 

* 예제(ThisParameterType, OmitThisParameter)

function a(this: Window | typeof obj, param: string) {
    console.log(this)
}

const obj = {name: "zerocho"}
const b = a.bind(obj)
b(); //zerocho

//(this를 추출) type T =  Window | typeof obj
type T = ThisParameterType<typeof a>
//(this를 없앰) type NoThis = (param: string) => void
type NoThis = OmitThisParameter<typeof a>

 

 

* bind 

▶ 1. this를 쓰는 경우

▶ 2. this를 쓰지 않는 경우

 

 

* 예제 : bind(this를 쓰는 경우)

const zerocho = {
    name: "zerocho",
    sayHello(this: {name: string}) {
        console.log(`hi, ${this.name}`);
    }
}
//sayHello는 this가 있으나 sayHi는 this가 없음(bind의 ThisParameterType, OmitThisParameter 때문)
const sayHello = zerocho.sayHello;
//sayHi의 this는 name: 'nero'
const sayHi = zerocho.sayHello.bind({name: "nero"});
sayHi(); //bind 통해서 this가 zerocho에서 nero로 바뀜

 

 

* 예제 : bind(this를 쓰지 않는 경우)

function add(a: number, b: number, c: number, d: number, e: number, f: number) {
    return a + b + c + d + e + f;
}

const add1 = add.bind(null);
add(1, 2, 3, 4, 5, 6);

const add2 = add.bind(null, 1); //매개변수 자리에 미리 값을 갖다 놓음
add2(2, 3, 4, 5, 6);

const add3 = add.bind(null, 1, 2);
add3(3, 4, 5, 6);

const add4 = add.bind(null, 1, 2, 3);
add4(4, 5, 6);

const add5 = add.bind(null, 1, 2, 3, 4);
add5(5, 6);

//bind<T, A0, A extends any[], R>(this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0): (...args: A) => R;

// const add2 = add.bind(null, 1); 
// add2(2, 3, 4, 5, 6);

//매개변수 : (this: (this: T, arg0: A0, ...args: A) => R, thisArg: T, arg0: A0)
//함수의 리턴값 : (...args: A) => R
//this는 함수
//thisArg: T = null
//arg0: A0 = 1
//...args: A = 2, 3, 4, 5, 6