我定义了一个 AbstractModel
像这样:
export interface AbstractModel {
[key: string]: any
}
然后我声明类型
Keys
:export type Keys = keyof AbstractModel;
我希望任何具有 Keys 类型的东西都会被单义地解释为一个字符串,例如:
const test: Keys;
test.toLowercase(); // Error: Property 'toLowerCase' does not exist on type 'string | number'. Property 'toLowerCase' does not exist on type 'number'.
这是 Typescript (2.9.2) 的错误,还是我遗漏了什么?
最佳答案
正如 TypeScript 2.9 的发行说明中所定义的,如果您使用字符串索引签名对接口(interface)进行 keyof,它将返回字符串和数字的并集
Given an object type X, keyof X is resolved as follows:
If X contains a string index signature, keyof X is a union of string, number, and the literal types representing symbol-like properties, otherwise
If X contains a numeric index signature, keyof X is a union of number and the literal types representing string-like and symbol-like properties, otherwise
keyof X is a union of the literal types representing string-like, number-like, and symbol-like properties.
source
这是因为:JavaScript 在索引对象时将数字转换为字符串:
[..] when indexing with a number, JavaScript will actually convert that to a string before indexing into an object. That means that indexing with 100 (a number) is the same thing as indexing with "100" (a string), so the two need to be consistent.
source
例子:
let abc: AbstractModel = {
1: "one",
};
console.log(abc[1] === abc["1"]); // true
当您只需要字符串键时,您只能从界面中提取字符串键,如下所示:
type StringKeys = Extract<keyof AbstractModel, string>;
const test: StringKeys;
test.toLowerCase(); // no error
TypeScript 编译器还提供了一个选项来获得
keyof
的 2.9 之前的行为。 :keyofStringsOnly (boolean) default
false
Resolve
keyof
to string valued property names only (no numbers or symbols).
source
关于typescript - Keyof 推断字符串 |键只是字符串时的数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51808160/