使用映射类型将泛型类型的数组映射到其他(返回)数组

时间:2019-05-06 08:24:44

标签: typescript generics

我有一个函数,该函数接受可变数量的输入参数,并返回相同长度的数组,其中的项具有调用该函数时指定的通用类型。它实际上是一个返回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>]

当前是否可以使用映射类型?还是需要指定重载?

2 个答案:

答案 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;
  }