typescript - 基于另一个属性值的动态类型属性
问题描述
我正在制作一种类型来强制DynamicColor
正确使用这种类型。
enum ColorsEnum {
red = "red",
green = "green",
blue = "blue",
yellow = "yellow",
}
type ColorsMapperType = {
type: ColorsEnum
red: {
redProperty: string
}
green: {
greenProperty: string
}
blue: {
blueProperty: string
}
yellow: {
yellowProperty: string
}
}
type ColorsMapper = Omit<ColorsMapperType, "type">
export type DynamicColor = {
[ColorType in keyof ColorsMapper]: {
[Prop in 'type' | ColorType]: Prop extends 'type' ? ColorType : ColorsMapper[ColorType]
}
}[keyof ColorsMapper]
Codesandbox:https ://codesandbox.io/s/naughty-sanderson-niqez?file=/src/index.ts
我大部分时间都在工作,但是我希望类型中的type
字段DynamicColor
是正确的ColorEnum
类型。
现在,我得到了字符串值的自动完成ColorEnum
,但不是实际的枚举类型。
例如,以下代码应该是有效的:
const color: DynamicColor = {
type: ColorsEnum.green,
green: {
greenProperty: "1",
},
}
以下代码均无效
const color0: DynamicColor = {
type: "green", // invalid because not of ColorsEnum type
green: {
greenProperty: "1",
},
}
const color1: DynamicColor = {
type: ColorsEnum.blue, // invalid because property "blue" is not included
}
const color2: DynamicColor = {
type: ColorsEnum.blue, // invalid because color property does not match correct type (ColorsEnum.blue should require a "blue" property)
green: {
greenProperty: "1",
}
}
const color3: DynamicColor = {
type: ColorsEnum.blue, // invalid because more than one color property is included
blue: {
blueProperty: "1",
}
green: {
greenProperty: "1",
}
}
有没有办法做到这一点?在此先感谢,如果还有其他方法可以改进此代码,我会全力以赴。
解决方案
您基本上想将 中的所有项目映射ColorsEnum
到另一种类型,例如 (pseudocode)
{ type: T; [T]: ColorsMapper[T] }
。幸运的是,条件类型可以做到这一点。这是我找到的解决方案。
enum ColorsEnum {
red = "red",
green = "green",
blue = "blue",
yellow = "yellow",
}
type ColorsMapper = {
type: ColorsEnum
red: {
redProperty: string
}
green: {
greenProperty: string
}
blue: {
blueProperty: string
}
yellow: {
yellowProperty: string
}
}
type MapToColorType<T> = T extends ColorsEnum ? { [key in T]: ColorsMapper[T] } & { type: T } : never;
type Result = MapToColorType<ColorsEnum>;
const color: Result = {
type: ColorsEnum.green,
green: {
greenProperty: "1",
},
}
你可以在这里玩弄它。
解释
问题是条件类型分布在联合类型上。这意味着该条件适用于工会的所有成员。枚举基本上是所有可能值的联合。我们可以利用它来将枚举的每个成员映射到特定类型。
推荐阅读
- ios - 在另一个自定义类的子类中运行集合视图补充视图时出现 Swift 错误
- ansible - 带有私有注册表的 Ansible docker_swarm_service
- git - 如何解决分歧的分支和 orgin/branch?
- html - CSS列:列宽取决于每列的最大项目长度
- c# - 在相同的 url 上重定向导致重定向过多
- reactjs - React + Express:Axios 在 Heroku 上返回 405 Method Not Allowed
- c - 如何使用双指针在 C 中操作数组?
- c# - Char.Parse("P") 在 C# 中返回 80 'P'
- html - 剪辑路径多边形圆边
- ruby - 液体 - 除非 for.loop 似乎总是最后一个