为什么 Typescript 在使用 [key in enum] 索引签名时不将枚举成员识别为有效属性
Why Does Typescript not Recognize Enum Members as Valid Properties When Using [key in enum] Index Signature
我正在处理一个 TypeScript 项目,在使用枚举成员作为接口的索引键时,我 运行 遇到了一个奇怪的问题。我的枚举和接口都在全局 .d.ts 文件中声明(没有导入或导出)。
// enums.d.ts
...
enum ItemFlag {
IsPushable = "isPushable",
IsTakable = "isTakable",
IsUnique = "isUnique"
}
...
// interfaces.d.ts
...
interface IThingProps {
id: string;
name: string;
}
interface IItemProps extends IThingProps {
[key in ItemFlag]?: boolean;
}
...
但是,当我尝试创建一个实现 IItemProps
接口的对象时:
const props: IItemProps = {
id: "item_small_cup",
name: "small cup",
[ItemFlag.IsTakable]: true
};
我收到以下错误:
“类型‘{ id: string; name: string; isTakable: boolean; }’不可分配给类型 'IItemProps'。
对象字面量只能指定已知属性,并且类型 'IItemProps' 中不存在“[ItemFlag.IsTakable]”。
奇怪的是我用另一个枚举来做这件事而且它工作正常。唯一的区别是我使用它内联声明对象的类型,如:
const genders: {[key in Gender]: Pronouns; } = {
[Gender.It]: {
they: "it",
them: "it",
// You get the idea
}
}
我想这个例子也没有 属性 作为可选,但是删除了可选的 '?' ItemFlag
的索引签名根本不会改变错误。
对这种奇怪的、前后矛盾的行为有什么看法吗?
尝试使用类型而不是接口:
enum ItemFlag {
IsPushable = "isPushable",
IsTakable = "isTakable",
IsUnique = "isUnique"
}
type IThingProps = {
id: string;
name: string;
}
type IItemProps = IThingProps & {
[key in ItemFlag]?: boolean;
}
const props: IItemProps = {
id: "item_small_cup",
name: "small cup",
[ItemFlag.IsTakable]: true
};
您要构建的是 Mapped Type
并且打字稿不支持映射接口。或者至少您将无法在接口上定义具体的 property/method。
根据一般经验,除非需要接口,否则我会使用类型。
这是一个有用的答案,它描述了两者之间的区别。
我正在处理一个 TypeScript 项目,在使用枚举成员作为接口的索引键时,我 运行 遇到了一个奇怪的问题。我的枚举和接口都在全局 .d.ts 文件中声明(没有导入或导出)。
// enums.d.ts
...
enum ItemFlag {
IsPushable = "isPushable",
IsTakable = "isTakable",
IsUnique = "isUnique"
}
...
// interfaces.d.ts
...
interface IThingProps {
id: string;
name: string;
}
interface IItemProps extends IThingProps {
[key in ItemFlag]?: boolean;
}
...
但是,当我尝试创建一个实现 IItemProps
接口的对象时:
const props: IItemProps = {
id: "item_small_cup",
name: "small cup",
[ItemFlag.IsTakable]: true
};
我收到以下错误:
“类型‘{ id: string; name: string; isTakable: boolean; }’不可分配给类型 'IItemProps'。 对象字面量只能指定已知属性,并且类型 'IItemProps' 中不存在“[ItemFlag.IsTakable]”。
奇怪的是我用另一个枚举来做这件事而且它工作正常。唯一的区别是我使用它内联声明对象的类型,如:
const genders: {[key in Gender]: Pronouns; } = {
[Gender.It]: {
they: "it",
them: "it",
// You get the idea
}
}
我想这个例子也没有 属性 作为可选,但是删除了可选的 '?' ItemFlag
的索引签名根本不会改变错误。
对这种奇怪的、前后矛盾的行为有什么看法吗?
尝试使用类型而不是接口:
enum ItemFlag {
IsPushable = "isPushable",
IsTakable = "isTakable",
IsUnique = "isUnique"
}
type IThingProps = {
id: string;
name: string;
}
type IItemProps = IThingProps & {
[key in ItemFlag]?: boolean;
}
const props: IItemProps = {
id: "item_small_cup",
name: "small cup",
[ItemFlag.IsTakable]: true
};
您要构建的是 Mapped Type
并且打字稿不支持映射接口。或者至少您将无法在接口上定义具体的 property/method。
根据一般经验,除非需要接口,否则我会使用类型。
这是一个有用的答案,它描述了两者之间的区别。