我觉得这个问题类似于以下问题: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
答案 0 :(得分:0)
因为您的枚举表达式编译为JavaScript,该JavaScript定义了具有属性ID
和NAME
的对象,基本上是这样的:
var AcmeFields = {
ID: "id",
NAME: "name"
};
鉴于此,应该清楚为什么需要使用ID
和NAME
来访问枚举成员:"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]
。
由于可能会混淆字符串枚举,因此通常我建议定义属性名称与值相同的字符串枚举。