我有一个函数,该函数接受可变数量的输入参数,并返回相同长度的数组,其中的项具有调用该函数时指定的通用类型。它实际上是一个返回Promise
数组的函数。
我使用映射类型来做到这一点:
export const Service = {
/* ... */
promisify: <T extends [] = any>(...p: Array<string>): { [P in keyof T]: Promise<T[P]> } => {
const result = [];
/* ... */
return result;
}
}
但是它给出了错误,因为一个对象被声明为返回类型...
我要实现的目标是在这些行中添加一些东西:
/*pseudocode*/
export const Service = {
promisify: <T extends [] = any>(...p: Array<string>): [ [P in keyof T]: Promise<T[P]> ] => {
const result = [];
/* ... */
return result;
}
}
我追求的结果是能够调用此函数并具有正确的返回类型:
Service.promisify<number>("val1"); //=> [Promise<number>]
Service.promisify<number, string>("val1", "val2"); //=> [Promise<number>, Promise<string>]
Service.promisify<number, string, MyType>("val1", "val2", "val3"); //=> [Promise<number>, Promise<string>, Promise<MyType>]
当前是否可以使用映射类型?还是需要指定重载?
答案 0 :(得分:1)
您的一般想法应该可行,您只在语法方面遇到了几个问题。没有映射的元组语法,但是常规的映射类型可以按预期的那样与元组一起使用(自3.1起)。
此外,您需要将T
约束为数组类型,并且需要将要映射的类型作为元组传递:
export const Service = {
promisify: <T extends any[]>(): { [P in keyof T]: Promise<T[P]> } => {
const result = [] as any as { [P in keyof T]: Promise<T[P]> };
/* ... */
return result;
}
}
Service.promisify<[number]>(); //=> [Promise<number>]
Service.promisify<[number, string]>(); //=> [Promise<number>, Promise<string>]
Service.promisify<[number, string, MyType]>(); //=> [Promise<number>, Promise<string>, Promise<MyType>]
答案 1 :(得分:0)
promisify()
返回一个对象。如果要返回对象,请使用{}
对其进行初始化,并使用as MyType
定义其类型,则将推断方法的返回类型。我还更喜欢A[]
(更多的Typescript方式)而不是Array<A>
(更多的C#/ Java方式):
promisify: <T extends [] = any>(...p: string[]) => {
const result = {} as { [P in keyof T]: Promise<T[P]> };
/* ... */
return result;
}