避免任何类型在typescript中获取枚举值

避免任何类型在typescript中获取枚举值,typescript,Typescript,我需要循环遍历枚举类型以填充react组件中的一些选项。 在枚举和从中重新解压缩键和值的函数下面查找 export enum ProyectType { time, hits, value, results } function projectTypeValues() { const values = Object.keys(ProyectType).filter(k => typeof ProyectType[k as any] === "numbe

我需要循环遍历枚举类型以填充react组件中的一些选项。 在枚举和从中重新解压缩键和值的函数下面查找

export enum ProyectType {
  time, 
  hits, 
  value, 
  results
}

function projectTypeValues() {
  const values = Object.keys(ProyectType).filter(k => typeof ProyectType[k as any] === "number"); // ["time", "hits", "value", "results"]
  const keys = values.map(k => ProyectType[k as any]); // [0, 1, 2, 3]
}
我不喜欢
ProyectType[k as any]
中的
any
类型,因此我尝试:

type EnumIndex = number | string;
ProyectType[k as EnumIndex]
但是我得到:
元素隐式地具有“any”类型,因为索引表达式不是“number”类型。ts(7015)

我认为索引器可以是number或string类型,就像
对象一样。Keys
是由8个元素组成的数组:
[“0”、“1”、“2”、“3”、“time”、“hits”、“value”、“results”]
但这两个元素都不起作用


如果枚举类型已知,在这种情况下如何删除
任何
类型?

是的,这真的很奇怪,似乎只发生在某些函数中

看看这种方法:

const keys = [];
const values = [];
for(const index in ProyectType){
   //typescript infers string to index const  but here there is no error
  typeof ProyectType[index] === "number" ? values.push(index) : keys.push(index)
 
}
使用无错误编写代码的方法的一个可能的解决方案是使用未知类型+数字

const values = Object.keys(ProyectType).filter(k => typeof ProyectType[k as unknown as number] === "number"); // ["time", "hits", "value", "results"]

是的,这真的很奇怪,它似乎只发生在一些函数中

看看这种方法:

const keys = [];
const values = [];
for(const index in ProyectType){
   //typescript infers string to index const  but here there is no error
  typeof ProyectType[index] === "number" ? values.push(index) : keys.push(index)
 
}
使用无错误编写代码的方法的一个可能的解决方案是使用未知类型+数字

const values = Object.keys(ProyectType).filter(k => typeof ProyectType[k as unknown as number] === "number"); // ["time", "hits", "value", "results"]

这里的主要问题是返回类型为
string[]
,而不是类似于
Array

这是有意的:TypeScript中的对象类型是打开的,而不是关闭的;它们必须具有一组已知属性,但可能具有其他属性。有关更多详细信息,请参阅Q/A对

因此,编译器看到您试图使用任意的
字符串
索引到
ProyectType
,对此并不满意。如果您不关心额外键的可能性,或者如果您碰巧知道这些键将是什么,那么您可以使用a来告诉编译器它无法理解的内容

例如,您可以这样做:

type ProyectTypeKeys = Array<keyof typeof ProyectType | number>;
// type ProyectTypeKeys = (number | "time" | "hits" | "value" | "results")[]

const values = (Object.keys(ProyectType) as ProyectTypeKeys).
    filter((k): k is keyof typeof ProyectType =>
        typeof ProyectType[k] === "number");
// const values: ("time" | "hits" | "value" | "results")[]

const keys = values.map(k => ProyectType[k]);
// const keys: ProyectType[]
type ProyectTypeKeys=数组;
//键入ProyectTypeKeys=(number |“time”|“hits”|“value”|“results”)[]
常量值=(Object.keys(ProyectType)作为ProyectTypeKeys)。
过滤器((k):k是ProyectType=>
项目类型[k]=“编号”);
//常量值:(“时间”|“命中”|“值”|“结果”)[]
constkeys=values.map(k=>ProyectType[k]);
//常量键:ProyectType[]
这里我将
ProyectTypeKeys
定义为数组类型,其元素要么是enum对象的已知字符串键,要么是
number
。。。这就是您希望看到的,也是您执行
filter()
步骤的原因

类似地,我对
filter()
回调进行了注释,以便编译器使用它将
filter()
的输出类型从完整数组类型
ProyectTypeKeys
缩小到只输出的类型:
keyof typeof ProyectType
,也称为
“time”|“hits”|“value”|“results”

在此之后,根据需要,推断出的
键的类型为
ProyectType[]


这里的主要问题是返回类型为
string[]
,而不是类似于
数组的内容

这是有意的:TypeScript中的对象类型是打开的,而不是关闭的;它们必须具有一组已知属性,但可能具有其他属性。有关更多详细信息,请参阅Q/A对

因此,编译器看到您试图使用任意的
字符串
索引到
ProyectType
,对此并不满意。如果您不关心额外键的可能性,或者如果您碰巧知道这些键将是什么,那么您可以使用a来告诉编译器它无法理解的内容

例如,您可以这样做:

type ProyectTypeKeys = Array<keyof typeof ProyectType | number>;
// type ProyectTypeKeys = (number | "time" | "hits" | "value" | "results")[]

const values = (Object.keys(ProyectType) as ProyectTypeKeys).
    filter((k): k is keyof typeof ProyectType =>
        typeof ProyectType[k] === "number");
// const values: ("time" | "hits" | "value" | "results")[]

const keys = values.map(k => ProyectType[k]);
// const keys: ProyectType[]
type ProyectTypeKeys=数组;
//键入ProyectTypeKeys=(number |“time”|“hits”|“value”|“results”)[]
常量值=(Object.keys(ProyectType)作为ProyectTypeKeys)。
过滤器((k):k是ProyectType=>
项目类型[k]=“编号”);
//常量值:(“时间”|“命中”|“值”|“结果”)[]
constkeys=values.map(k=>ProyectType[k]);
//常量键:ProyectType[]
这里我将
ProyectTypeKeys
定义为数组类型,其元素要么是enum对象的已知字符串键,要么是
number
。。。这就是您希望看到的,也是您执行
filter()
步骤的原因

类似地,我对
filter()
回调进行了注释,以便编译器使用它将
filter()
的输出类型从完整数组类型
ProyectTypeKeys
缩小到只输出的类型:
keyof typeof ProyectType
,也称为
“time”|“hits”|“value”|“results”

在此之后,根据需要,推断出的
键的类型为
ProyectType[]

使用类型断言 这是一种优雅而另类的方式;)考虑到
enum
s只能包含
string
number
类型,并且您的操作是有意的,您可以使用类型断言来获取值和键。类型转换(或断言)是向编译器表明您知道自己在做什么的一种方式。你可以在找到更多信息

在您的情况下,函数应如下所示:

function projectTypeValues() {
  const values = Object.values(ProyectType)
                .filter((val) => isNaN(val as number));
  const keys = Object.keys(ProyectType)
              .filter(key => !isNaN(key as unknown as number))
              .map(key => +key);
}
我使用了与数字一样未知的
键,因为在本例中,我们的键是
string
。然后,我将它们映射为在编写时将字符串转换为数字。

使用类型断言 这是一种优雅而另类的方式;)考虑到
enum
s只能包含
string
number
类型,并且您的操作是有意的,您可以使用类型断言来获取值和键。类型转换(或断言)是向编译器表明您知道自己在做什么的一种方式。你可以在找到更多信息

在您的情况下,函数应如下所示:

function projectTypeValues() {
  const values = Object.values(ProyectType)
                .filter((val) => isNaN(val as number));
  const keys = Object.keys(ProyectType)
              .filter(key => !isNaN(key as unknown as number))
              .map(key => +key);
}
我使用了与数字一样未知的