字符串枚举作为映射键不适用于ReturnType

时间:2019-03-19 05:17:46

标签: typescript

我正在尝试为functions分配类型。以下代码有效。

enum Enum {
  Foo = "foo"
}

const functions = {
  [Enum.Foo]: () => "Hello World!"
};

type FunctionMap = { [key: string]: (...args: any[]) => any };
type FunctionUnion<T extends FunctionMap> = ReturnType<T[keyof T]>;

type functions = FunctionUnion<typeof functions>;

但是,如果我更改了FunctionMap的密钥类型,

type FunctionMap = { [key in Enum]: (...args: any[]) => any };

它抛出

  

类型'T [keyof T]'不满足约束'(... args:any [])=> any'。     类型'FunctionMap [keyof T]'不能分配给类型'(... args:any [])=> any'.ts(2344)

为什么会引发错误?

1 个答案:

答案 0 :(得分:2)

您会遇到枚举错误,因为索引签名[key: string]意味着FunctionMap上可能存在的任何属性都必须为(...args: any[]) => any类型。另一方面,Enum上的映射类型意味着枚举中存在的属性必须是函数,而该类型不能保证其他属性。所以这是有效的:

enum Enum {
  Foo = "foo"
}

const functions = {
  [Enum.Foo]: () => "Hello World!",
  otherProp: "string"
};

type FunctionMap = { [key in Enum]: (...args: any[]) => any };
type FunctionUnion<T extends FunctionMap> = ReturnType<T[keyof T]>;
type functions = FunctionUnion<typeof functions>; //ok  here otherProp is not a problem

一种选择是使用条件类型过滤掉非函数类型:

enum Enum {
  Foo = "foo"
}

const functions = {
  [Enum.Foo]: () => "Hello World!",
  otherProp: "string"
};

type FunctionMap = { [key in Enum]: (...args: any[]) => any };
type FunctionUnion<T extends FunctionMap> = { 
    [P in keyof T]: T[P] extends (...args: any[]) => any ? ReturnType<T[P]> : never;
}[keyof T]
type functions = FunctionUnion<typeof functions>;