컨텍스트
최근 타사 라이브러리의 "약속"작업을하고있었습니다. 기본적으로 라이브러리는 마지막 인수로 콜백을 사용하는 NodeJS 비동기 스타일 함수로 가득합니다. 나는. 이것과 같은 서명이 기능 : 그럼일반화 된 "promisify"함수에서 typescript 형식 유추
function cb<TResult>(
resolve: (res: TResult) => void,
reject: (err: any) => void
): (actualError, actualResult) => void {
return (error, result) => error ? reject(error) : resolve(result);
}
:
function foo(arg1: string, arg2: number, ..., callback: (error, result) => void): void
나는 Promise<T>
돌아 것들로 그들을 원래의 기능을 포장에 대한 코드를 줄이고 만들 수있는 함수를 작성하려
patchUserMetadata(userId: string, userMetadata: any): Promise<a0.Auth0UserProfile> {
return new Promise((resolve, reject) =>
this.wrapped.patchUserMetadata(userId, userMetadata, cb(resolve, reject)));
}
linkUser(userId: string, secondaryUserToken: string): Promise<any> {
return new Promise((resolve, reject) =>
this.wrapped.linkUser(userId, secondaryUserToken, cb(resolve, reject)));
}
// ... and so on, and on, and on...
: 방법을 promisify, 나는 그런 코드를 작성하는 것
쉽게 볼 수 있듯이, 저는 여전히 TypeScript에 익숙하지 않고 기본적으로 바퀴를 재발 명하려고했습니다. 내 바퀴는 육각형되고 결국 나는 내 코드를 검토
누군가가 내가 저렴한 비용으로 비슷한 결과를 달성하기 위해 js-promisify
을 사용할 수 있다는 지적 ... 손으로 너무 많은 포장 코드를 작성 유지했다.
module.exports = function (fun, args, self) {
return new Promise(function (resolve, reject) {
args.push(function (err, data) {
err && reject(err);
resolve(data);
})
fun.apply(self, args);
});
};
내가 타이프 라이터가 아닌 자바 스크립트를 처리하고있어 이후로, 내가 더 나아가 연구의 조금을했다 : 라이브러리는 작업을 수행하는 도우미를 정의합니다. 내가 typed-promisify
따기 결국하고 코드가 지금과 같은 모습입니다 : 훨씬 깔끔한
patchUserMetadata = promisify(this.wrapped.patchUserMetadata);
linkUser = promisify(this.wrapped.linkUser);
, 응? 내가 방법을 정확하게 궁금
이 promisify
기능 작업 가까이 않습니다 얻기? 나는 소스 코드를 보면서 js-promisify
의 유사한 작동하는 솔루션을 발견
export function promisify<T>(f: (cb: (err: any, res: T) => void) => void, thisContext?: any):() => Promise<T>;
export function promisify<A, T>(f: (arg: A, cb: (err: any, res: T) => void) => void, thisContext?: any): (arg: A) => Promise<T>;
export function promisify<A, A2, T>(f: (arg: A, arg2: A2, cb: (err: any, res: T) => void) => void, thisContext?: any): (arg: A, arg2: A2) => Promise<T>;
// ...more overloads
export function promisify(f: any, thisContext?: any) {
return function() {
let args = Array.prototype.slice.call(arguments);
return new Promise((resolve, reject) => {
args.push((err: any, result: any) => err !== null ? reject(err) : resolve(result));
f.apply(thisContext, args);
});
}
}
질문
당신이 밀접하게 promisify
보면,이 솔루션은 정말 일반화되지 않은 것을 볼 수 있습니다. 의미, 만약 내가 10 + 매개 변수와 함수를 promisify, 거기에 대한 일치하는 과부하가 필요하지 않았다. 구현은 여전히 잘 작동하지만이 경우 유형 정보가 손실됩니다.
정교한 오버로드를 모두 정의하지 않고 정확한 함수 유형 (또는 시그너처, 개수 및 유형 매개 변수)을 추론하는 방법이 TypeScript에 있습니까?
나는이 [분명, 의사] 같은 뭔가를 찾고 있어요 :
export function promisify<...[TArgs], T>(
f: (...allArgsButLastTwo: [TArgs],
cb: (err: any, res: T) => void) => void,
thisContext?: any
): (...[TArgs]) => Promise<T>;
export function promisify(
...allArgsButLastTwo: any[],
f: any,
thisContext?: any
) {
return function() {
let args = Array.prototype.slice.call(arguments);
return new Promise((resolve, reject) => {
args.push((err: any, result: any) => err !== null ? reject(err) : resolve(result));
f.apply(thisContext, args);
});
}
}
나는 내가 무엇을 찾고 있어요 것은 하지 달성하는 느낌이 긴 오버로드 목록이이었다 그 이유는 저자가 사용하던 최후의 수단/절충안이 해결 될 때까지 버전 2.5로
감사합니다. TS 문제 및 로드맵 Filipe를 참조하십시오. –