【问题标题】:How to type enum values mapped from key correctly如何正确键入从键映射的枚举值
【发布时间】:2019-06-07 07:58:38
【问题描述】:

我尝试使用这两个函数来获取枚举的键和值。他们似乎工作,我已经弄清楚了大部分的打字,只剩下一个错误,我希望在 TypeScript 中比我更聪明的人可以帮助解决......

const isInteger = /^\d+$/;

export const enumKeys = <T>(enumObj: T): string[] => {
  return Object.keys(enumObj).filter(k => !isInteger.test(k));
};

export const enumValues = <T>(enumObj: T): T[keyof T][] => {
  return enumKeys(enumObj).map(k => enumObj[k]);
};

问题是enumObj[k],它给出了这种类型的错误:

元素隐含地具有“任何”类型,因为类型“{}”没有索引签名。 ts(7017)

我知道我可以忽略警告,但我想学习,但我不明白为什么/这里隐含的 any 是什么,以及如何正确键入它而不是那样。


解决方案,基于接受的答案

const isInteger = /^\d+$/;

export const enumKeys = <T>(enumObj: T): (keyof T)[] => {
  return Object.keys(enumObj)
    .filter(k => !isInteger.test(k))
    .map(k => k as keyof T);
};

export const enumValues = <T>(enumObj: T): T[keyof T][] => {
  return enumKeys(enumObj).map(k => enumObj[k]);
};

【问题讨论】:

    标签: typescript enums


    【解决方案1】:

    较新版本的TS有如下错误

    Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'unknown'.
      No index signature with a parameter of type 'string' was found on type 'unknown'.ts(7053)
    

    类型参数T 没有类型约束,因此默认情况下它的约束是(unknown{} 取决于版本)。当您尝试使用enumObj[k] 进行索引时,k 的类型为string,但enumObj 不支持使用string 进行索引,因为它没有接受string 的索引签名。

    简单的解决方案是断言k 确实是T 的键:

    export const enumKeys = <T>(enumObj: T): string[] => {
      return Object.keys(enumObj).filter(k => !isInteger.test(k));
    };
    
    export const enumValues = <T>(enumObj: T): T[keyof T][] => {
      return enumKeys(enumObj).map(k => enumObj[k as keyof T]);
    };
    

    【讨论】:

    • 做到了!而且我也能够“翻转它”,所以enumKeys 也不会在其他地方引起这个错误。将调整后的代码添加到我的问题中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    相关资源
    最近更新 更多