打字稿:属性 的类型依赖于同一对象内的另一个 属性
Typescript: Type of a property dependent on another property within the same object
我有一个带有两个属性(type:string
和 args:object
)的 TypeScript 接口。根据 type
,args
可能具有不同的属性。我需要将什么类型定义应用于 args
,以便 compiler/autocomplete 知道哪些属性允许用于 args
?
这有点类似于我在 Redux 中使用 Actions 的方式,它有一个 type
和一个 payload
并且在我的 reducer 中,编译器通过 switch 语句知道负载包含什么。但我无法让它与我的对象一起使用。
我在这里阅读了一篇很棒的文章 https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/ 但这描述了具有两个相互依赖的参数的方法的问题,但没有说明如何使它对同一对象中的两个属性起作用。
export interface IObject {
type: ObjectType
parameters: ObjectParameters
}
export type ObjectType = "check" | "counter"
export interface IParametersCheck {
checked: boolean
}
export interface IParametersCounter {
max: number
min: number
step: number
}
export type ObjectParameters = IParametersCheck | IParametersCounter
如果我有一个 IObject
并将类型设置为 "check",则 compiler/autocomplete 应该提供 IParametersCheck
.
的属性
我认为你真正想要的是一个受歧视的工会。 IObject
本身应该是一个联合:
export type IObject = {
type: "checked"
parameters: IParametersCheck
} | {
type: "counter"
parameters: IParametersCounter
}
export type ObjectType = IObject['type'] //// in case you need this union
export type ObjectParameters = IObject['parameters'] //// in case you need this union
export interface IParametersCheck {
checked: boolean
}
export interface IParametersCounter {
max: number
min: number
step: number
}
您也可以使用条件类型来实现,但我认为联合解决方案效果更好:
export interface IObject<T extends ObjectType> {
type: T
parameters: T extends 'checked' ? IParametersCheck: IParametersCounter
}
或者用映射接口:
export interface IObject<T extends ObjectType> {
type: T
parameters: ParameterMap[T]
}
type ParameterMap ={
'checked': IParametersCheck
'counter': IParametersCounter
}
export type ObjectType = keyof ParameterMap
我有一个带有两个属性(type:string
和 args:object
)的 TypeScript 接口。根据 type
,args
可能具有不同的属性。我需要将什么类型定义应用于 args
,以便 compiler/autocomplete 知道哪些属性允许用于 args
?
这有点类似于我在 Redux 中使用 Actions 的方式,它有一个 type
和一个 payload
并且在我的 reducer 中,编译器通过 switch 语句知道负载包含什么。但我无法让它与我的对象一起使用。
我在这里阅读了一篇很棒的文章 https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/ 但这描述了具有两个相互依赖的参数的方法的问题,但没有说明如何使它对同一对象中的两个属性起作用。
export interface IObject {
type: ObjectType
parameters: ObjectParameters
}
export type ObjectType = "check" | "counter"
export interface IParametersCheck {
checked: boolean
}
export interface IParametersCounter {
max: number
min: number
step: number
}
export type ObjectParameters = IParametersCheck | IParametersCounter
如果我有一个 IObject
并将类型设置为 "check",则 compiler/autocomplete 应该提供 IParametersCheck
.
我认为你真正想要的是一个受歧视的工会。 IObject
本身应该是一个联合:
export type IObject = {
type: "checked"
parameters: IParametersCheck
} | {
type: "counter"
parameters: IParametersCounter
}
export type ObjectType = IObject['type'] //// in case you need this union
export type ObjectParameters = IObject['parameters'] //// in case you need this union
export interface IParametersCheck {
checked: boolean
}
export interface IParametersCounter {
max: number
min: number
step: number
}
您也可以使用条件类型来实现,但我认为联合解决方案效果更好:
export interface IObject<T extends ObjectType> {
type: T
parameters: T extends 'checked' ? IParametersCheck: IParametersCounter
}
或者用映射接口:
export interface IObject<T extends ObjectType> {
type: T
parameters: ParameterMap[T]
}
type ParameterMap ={
'checked': IParametersCheck
'counter': IParametersCounter
}
export type ObjectType = keyof ParameterMap