미리 정의 된 컨텍스트로 함수 집합을 실행하기위한 구성 함수를 만들려고합니다. 내 유형은 다음과 같습니다.
type Config<T> = {
context: T;
};
type Hooks<T> = {
hooks: T;
};
type FunctionWithThis<T> = (this: T, ...args) => any;
내 구성 함수에서 컨텍스트와 대상 함수를 병합하고 싶지만 함수에 대한 컨텍스트 매개 변수를 전달 this
합니다.
const configure = <TContext extends Object,
THooks extends Record<string, FunctionWithThis<TContext>>>
(config: Config<TContext> & Hooks<THooks>) => {
const result = {
get data() { return config.context; }
};
Object.entries(config.hooks).forEach((action) => {
result[action[0]] = (...args) => action[1].call(config.context, ...args);
});
return result as { data: TContext; } & THooks;
};
다음과 같이 사용할 수 있습니다.
const engine = configure({
context: {
foo: 12
},
hooks: {
log() {
console.log(this.foo); // this.foo is typed correctly here
}
}
});
const data = engine.data;
engine.log(); // error here
VS Code는 마지막 줄에 다음과 같은 오류를 제공합니다.
'{data : {foo : number; }; } & {log (this : {foo : number;}) : void; } '은 메소드의'this '유형'{foo : number; } '. '{데이터 : {foo : number; }; } & {log (this : {foo : number;}) : void; } '이지만'{foo : number; } '.
log
잘못된 컨텍스트에서 함수 를 호출하려고한다는 의미라고 생각합니다 . 출력의 각 기능에 대한 컨텍스트 유형을 변경할 수 있습니까?
아니면 그것을 해결할 다른 방법이 있습니까?
이후 THooks
유형의 구성원이 있어야합니다 (this: T, ...args: any[]) => any
,의 기능이 THooks
필요합니다 this
유형으로 TContext
. 그리고 당신의 함수는의 this
의지를 확실히 보장하지만 TContext
, 재조정 된 함수의 유형은 이것을 반영하지 않습니다. 이러한 함수 중 하나를 호출 할 때 지금 engine
의 형태에서, TS의 외모를 enigine
하고보고 그것은 적절하지 않다 this
에 대한 log
오류와 문제를 해결합니다.
this
구현 내부 를 전달하므로 this
결과 에서 매개 변수 를 지워야합니다 . 매핑 된 조건부 유형으로이를 수행 할 수 있습니다.
type Config<T> = {
context: T;
};
type Hooks<T> = {
hooks: T;
};
type FunctionWithThis<T> = (this: T, ...args: any[]) => any;
type RemoveThis<T extends Record<string, FunctionWithThis<any>>> = {
[P in keyof T]: T[P] extends (...a: infer A) => infer R ? (...a:A) => R: never
}
const configure = <TContext extends Object,
THooks extends Record<string, FunctionWithThis<TContext>>>
(config: Config<TContext> & Hooks<THooks>) => {
const result = {
get data() { return config.context; }
};
Object.entries(config.hooks).forEach((action) => {
(result as any)[action[0]] = (...args: any[]) => action[1].call(config.context, ...args);
});
return result as { data: TContext; } & RemoveThis<THooks>;
};
const engine = configure({
context: {
foo: 12
},
hooks: {
log() {
console.log(this.foo); // this.foo is typed correctly here
}
}
});
const data = engine.data;
engine.log(); // ok
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다