为普通函数添加 d.ts,其中 returns 是一个包装函数的函数
Adding d.ts for vanilla function which returns a function that wraps functions
我的 vanilla JS 代码中有一个复杂的函数(请参阅后面的简单示例)获取 export
d,我想向其添加一个 d.ts
。
到目前为止,我尝试编写 .d.ts
还没有将类型从中间阶段转发到最后阶段
function/s看起来像这样(我在保持相同结构的同时尽可能简化了它)
const factory = (x, y = 0) => {
const z = x + y;
return fn => {
const p = Promise.resolve(z).then(console.warn);
return (...args) => p.then(() => fn(...args));
};
};
用法示例
const A = factory(1, 2);
const fn = (a1, a2) => a1 + ' world' + a2; // (a1: string, a2: string) => string
const B = A(fn); // (i: string, j: string) => Promise<string>
B('hello', '!'); // warns 3 and returns a Promise<string> "hello world!"
因此,正如您从我的评论中看到的那样,调用 B
时预期的 arg 类型与 fn
相同,B
的 return 类型是fn
的 return 类型的
到目前为止我尝试了什么
declare function factory(x: number):
(fn: (...U: any) => T) =>
(...U) => Promise<T>;
declare function factory(x: number, y: number):
(fn: (...U: any) => T) =>
(...U) => Promise<T>;
然而,
- 当查看
B
时,关于 fn
的所有类型信息都丢失了,当我期望 (string, string) => Promise<string>
时,我只剩下 any[] => Promise<any>
- return 类型的描述重复多次
我也试过以 interface-y 的方式编写,但这有同样的类型丢失问题,我不知道你如何引用它们
declare function factory(x: number): wrapper;
declare function factory(x: number, y: number): wrapper;
interface wrapper {
(fn: function): wrapped;
}
interface wrapped {
(...args: any): Promise<any>;
}
如果我理解正确的话,你希望最终函数与你作为参数传递的函数具有相同的参数。虽然您不能对任意数量的参数执行此操作,但您可以为最多包含 4 个参数的函数定义重载,并在以后需要时添加更多参数:
declare function factory(x: number): Promiseify;
declare function factory(x: number, y: number): Promiseify;
interface Promiseify {
<T>(fn: () => T): () => Promise<T>;
<T, U1>(fn: (arg1: U1) => T): (arg1: U1) => Promise<T>;
<T, U1, U2>(fn: (arg1: U1, arg2: U2) => T): (arg1: U1, arg2: U2) => Promise<T>;
<T, U1, U2, U3>(fn: (arg1: U1, arg2: U2, arg3: U3) => T): (arg1: U1, arg2: U2, arg3: U3) => Promise<T>;
<T, U1, U2, U3, U4>(fn: (arg1: U1, arg2: U2, arg3: U3, arg4: U4) => T): (arg1: U1, arg2: U2, arg3: U3, arg4: U4) => Promise<T>;
}
const A = factory(1, 2);
const fn = (a1: string, a2: number) => a1 + ' world' + a2; // (a1: string, a2: number) => string
const B = A(fn); // (arg1: string, arg2: number) => Promise<string>
B('hello', 1); // ok
B('hello', '1'); // error
我的 vanilla JS 代码中有一个复杂的函数(请参阅后面的简单示例)获取 export
d,我想向其添加一个 d.ts
。
到目前为止,我尝试编写 .d.ts
还没有将类型从中间阶段转发到最后阶段
function/s看起来像这样(我在保持相同结构的同时尽可能简化了它)
const factory = (x, y = 0) => {
const z = x + y;
return fn => {
const p = Promise.resolve(z).then(console.warn);
return (...args) => p.then(() => fn(...args));
};
};
用法示例
const A = factory(1, 2);
const fn = (a1, a2) => a1 + ' world' + a2; // (a1: string, a2: string) => string
const B = A(fn); // (i: string, j: string) => Promise<string>
B('hello', '!'); // warns 3 and returns a Promise<string> "hello world!"
因此,正如您从我的评论中看到的那样,调用 B
时预期的 arg 类型与 fn
相同,B
的 return 类型是fn
到目前为止我尝试了什么
declare function factory(x: number):
(fn: (...U: any) => T) =>
(...U) => Promise<T>;
declare function factory(x: number, y: number):
(fn: (...U: any) => T) =>
(...U) => Promise<T>;
然而,
- 当查看
B
时,关于fn
的所有类型信息都丢失了,当我期望(string, string) => Promise<string>
时,我只剩下 - return 类型的描述重复多次
any[] => Promise<any>
我也试过以 interface-y 的方式编写,但这有同样的类型丢失问题,我不知道你如何引用它们
declare function factory(x: number): wrapper;
declare function factory(x: number, y: number): wrapper;
interface wrapper {
(fn: function): wrapped;
}
interface wrapped {
(...args: any): Promise<any>;
}
如果我理解正确的话,你希望最终函数与你作为参数传递的函数具有相同的参数。虽然您不能对任意数量的参数执行此操作,但您可以为最多包含 4 个参数的函数定义重载,并在以后需要时添加更多参数:
declare function factory(x: number): Promiseify;
declare function factory(x: number, y: number): Promiseify;
interface Promiseify {
<T>(fn: () => T): () => Promise<T>;
<T, U1>(fn: (arg1: U1) => T): (arg1: U1) => Promise<T>;
<T, U1, U2>(fn: (arg1: U1, arg2: U2) => T): (arg1: U1, arg2: U2) => Promise<T>;
<T, U1, U2, U3>(fn: (arg1: U1, arg2: U2, arg3: U3) => T): (arg1: U1, arg2: U2, arg3: U3) => Promise<T>;
<T, U1, U2, U3, U4>(fn: (arg1: U1, arg2: U2, arg3: U3, arg4: U4) => T): (arg1: U1, arg2: U2, arg3: U3, arg4: U4) => Promise<T>;
}
const A = factory(1, 2);
const fn = (a1: string, a2: number) => a1 + ' world' + a2; // (a1: string, a2: number) => string
const B = A(fn); // (arg1: string, arg2: number) => Promise<string>
B('hello', 1); // ok
B('hello', '1'); // error