首页 > 解决方案 > 如何正确键入从键映射的枚举值

问题描述

我试图让这两个函数来获取枚举的键和值。它们似乎有效,而且我已经弄清楚了大部分打字,只剩下一个错误,我希望比我在 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]);
};

标签: typescriptenums

解决方案


较新版本的 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)

type 参数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]);
};

推荐阅读