枚举的遍历键给出了打字问题
traverse keys of enum gives typing issue
假设您要打印枚举的所有值
enum AnEnum {
a = 'a',
b = 'b'
}
const keys = Object.keys(AnEnum);
keys.forEach(key => {
console.log(AnEnum[key]);
});
这会产生以下错误
Element implicitly has an 'any' type because expression of type
'string' can't be used to index type 'typeof AnEnum'. No index
signature with a parameter of type 'string' was found on type 'typeof
AnEnum'
我只能通过添加 any
来解决这个问题
(AnEnum as any)[key]
但我想应该有更好的解决方案。有什么建议吗?
The Object.keys()
method is given a typing in the TypeScript standard library 像这样:
interface ObjectConstructor {
keys(o: object): string[];
}
return 类型是 string[]
。这意味着 Object.keys(obj)
是 Array<string>
类型的值,而 不是 类型 Array<keyof typeof obj>
的值(其中 the keyof
operator represents a union of the known keys of an object type). See 是对为什么。这里我只想说编译器不能保证一个对象只有它知道的键。
这意味着如果您尝试使用仅已知为 string
的键对对象进行索引,则只有在已知该对象具有 string
[=29= 时才有效] 和编译器警告。
在这种情况下,您确定您的对象只有已知键(例如,string enum
where there's no reverse mapping), you can use a type assertion 告诉编译器:
const keys = Object.keys(AnEnum) as Array<keyof typeof AnEnum>;
然后你的循环就会工作:
keys.forEach(key => {
console.log(AnEnum[key]); // okay
});
请注意 Object.keys(obj) as Array<keyof typeof obj>
不是万灵药。如果事实证明 obj
确实有比编译器知道的更多的键,更糟糕的是,这些键的 属性 值与已知键的值不是同一类型,那么你可以写编译正常但在运行时爆炸的东西:
interface Foo {
a: string,
b: string
}
const f = { a: "hello", b: "goodbye", c: 123 };
const foo: Foo = f; // okay, f is a valid Foo
(Object.keys(foo) as Array<keyof Foo>).forEach(k => console.log(foo[k].toUpperCase()));
// HELLO
// GOODBYE
// RUNTIME ERROR! foo[k].toUpperCase is not a function
所以要小心!
假设您要打印枚举的所有值
enum AnEnum {
a = 'a',
b = 'b'
}
const keys = Object.keys(AnEnum);
keys.forEach(key => {
console.log(AnEnum[key]);
});
这会产生以下错误
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof AnEnum'. No index signature with a parameter of type 'string' was found on type 'typeof AnEnum'
我只能通过添加 any
(AnEnum as any)[key]
但我想应该有更好的解决方案。有什么建议吗?
The Object.keys()
method is given a typing in the TypeScript standard library 像这样:
interface ObjectConstructor {
keys(o: object): string[];
}
return 类型是 string[]
。这意味着 Object.keys(obj)
是 Array<string>
类型的值,而 不是 类型 Array<keyof typeof obj>
的值(其中 the keyof
operator represents a union of the known keys of an object type). See
这意味着如果您尝试使用仅已知为 string
的键对对象进行索引,则只有在已知该对象具有 string
[=29= 时才有效] 和编译器警告。
在这种情况下,您确定您的对象只有已知键(例如,string enum
where there's no reverse mapping), you can use a type assertion 告诉编译器:
const keys = Object.keys(AnEnum) as Array<keyof typeof AnEnum>;
然后你的循环就会工作:
keys.forEach(key => {
console.log(AnEnum[key]); // okay
});
请注意 Object.keys(obj) as Array<keyof typeof obj>
不是万灵药。如果事实证明 obj
确实有比编译器知道的更多的键,更糟糕的是,这些键的 属性 值与已知键的值不是同一类型,那么你可以写编译正常但在运行时爆炸的东西:
interface Foo {
a: string,
b: string
}
const f = { a: "hello", b: "goodbye", c: 123 };
const foo: Foo = f; // okay, f is a valid Foo
(Object.keys(foo) as Array<keyof Foo>).forEach(k => console.log(foo[k].toUpperCase()));
// HELLO
// GOODBYE
// RUNTIME ERROR! foo[k].toUpperCase is not a function
所以要小心!