在Typescript界面​​中使用字符串枚举计算的属性无法使用点表示法进行访问

时间:2019-02-28 17:15:22

标签: typescript

我觉得这个问题类似于以下问题:Typescript interface, using string constants for properties,但我还是想确认这种行为。

说你有

enum AcmeFields {
  ID = 'id',
  NAME = 'companyName',
}

,然后是interface

interface AcmeInterface {
  [AcmeFields.ID]: string,
  [AcmeFields.NAME]?: string;
}

与这样说:
const sampleCompany: AcmeInterface = { id: 1, name: 'Sample Company' }

为什么我只能这样做? (打字稿为此提供了自动完成功能)

sampleCompany['id']
sampleCompany[AcmeFields.ID]
sampleCompany['companyName']
sampleCompany[AcmeFields.NAME]

不是吗? (无自动填充或识别功能)

sampleCompany.id
sampleCompany.companyName

1 个答案:

答案 0 :(得分:0)

因为您的枚举表达式编译为JavaScript,该JavaScript定义了具有属性IDNAME的对象,基本上是这样的:

var AcmeFields = {
    ID: "id",
    NAME: "name"    
};

鉴于此,应该清楚为什么需要使用IDNAME来访问枚举成员:"id""name"是非常重要的值,而不是结果对象的属性。 (您可以通过查看已编译的JavaScript或在TypeScript Playground中进行验证。)

因此,当您编写以下任何内容时:

sampleCompany['id']
sampleCompany[AcmeFields.ID]
sampleCompany['name']
sampleCompany[AcmeFields.NAME]

您正在编写表达式,以使用字符串动态访问对象的属性。所有这些都将返回undefined。 TypeScript允许这种访问而不会产生编译错误,但这并不意味着表达式有用。相反,您应该以{{1​​}}的形式访问您的枚举值,或者,如果需要,可以以AcmeFields.ID的形式访问。

只有当枚举成员为数字时,TypeScript编译器才会分配“反向映射”,因此,如果您具有:

AcmeFields[ "ID" ]

然后enum AcmeNumbers { FIRST = 1, THIRD = 3 }; AcmeNumbers.FIRST都得到AcmeNumbers[1]

由于可能会混淆字符串枚举,因此通常我建议定义属性名称与值相同的字符串枚举。