如果我声明了这样的对象:
const values = {
x: 5,
y: 6,
};
type Key = keyof typeof values;
Key
类型为"x" | "y"
,这很有意义,因为它们是values
对象的有效键。但是,在这种情况下:
const values2: {
[key: string]: number;
} = {
x: 5,
y: 6,
};
type Key2 = keyof typeof values2;
然后,Key2
类型为string | number
,这是有效的对象键类型。这没有什么意义,因为values2
对象被声明为其键始终为string
。
可能是什么原因造成的?以及如何声明与values2
类似的对象(例如,我限制了对象值的类型),然后像我对values
对象所做的那样获取有效的键?
答案 0 :(得分:2)
const values2: {
[key: string]: number;
} = {
x: 5,
y: 6,
};
type Key2 = keyof typeof values2; // number | string
这没有多大意义,因为values2对象被声明为其键始终是字符串。
可能是什么原因造成的?
number
已添加到keyof
in this PR。我不知道原因,但意图是对于索引签名{[key: string]: whatever}
,keyof
确实包含number
,但对于映射类型{[key in string]: whatever}
keyof
仅为string
。
公关行情:
给出对象类型X,X的键解析如下:
如果X包含字符串索引签名,则X的key是字符串,数字和表示符号型属性的文字类型的并集,否则
...
在映射类型{[P in K]:XXX}中,K中的每个字符串文字类型都引入了带有字符串名称的属性,K中的每种数字文字类型都引入了带有数字名称的属性,以及每种唯一的符号类型在K中引入具有唯一符号名称的属性。此外,如果K包含类型字符串,则引入字符串索引签名;如果K包含类型数字,则引入数字索引签名。
下一个问题:
又如何声明一个类似于values2的对象(例如,我限制对象的值的类型是什么),然后像我对values对象所做的那样获取有效键?
为什么您认为values2
的唯一有效键只有x
和y
?之后可以添加任何密钥。与values
不同,此编译过程不会出现任何错误:
const values2: {
[key: string]: number;
} = {
x: 5,
y: 6,
};
values2.z = 7; // ok