【问题标题】:String enum as map key does not work with ReturnType作为映射键的字符串枚举不适用于 ReturnType
【发布时间】:2019-08-09 13:44:22
【问题描述】:

我正在尝试为 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)

为什么会抛出错误?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您会遇到枚举错误,因为索引签名[key: string] 意味着FunctionMap 上可能存在的任何属性都必须是(...args: any[]) =&gt; 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>; 
    

    【讨论】:

    • 好吧,谁不明白。 [key in Enum] 只有被授权者密钥 Enum 是函数。因为FunctionUnion 使用的是T extends FunctionMap,这意味着T 可以有除Enum 之外的键,这可能不是一个函数。
    猜你喜欢
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2017-12-06
    • 2012-01-06
    • 1970-01-01
    • 2021-09-23
    相关资源
    最近更新 更多