获取带注释的对象类型的keyof

时间:2019-04-02 21:40:26

标签: typescript

如果我声明了这样的对象:

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对象所做的那样获取有效的键?

TypeScript Playground Link

1 个答案:

答案 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的唯一有效键只有xy?之后可以添加任何密钥。与values不同,此编译过程不会出现任何错误:

const values2: {
    [key: string]: number;
} = {
    x: 5,
    y: 6,
};

values2.z = 7; // ok