打字稿:属性的类型依赖于同一对象中的另一个属性 [英] Typescript: Type of a property dependent on another property within the same object

查看:26
本文介绍了打字稿:属性的类型依赖于同一对象中的另一个属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有两个属性的 TypeScript 接口(type:stringargs:object).args 可能具有不同的属性,具体取决于 type.我需要对 args 应用什么类型定义,以便编译器/自动完成功能知道 args 允许哪些属性?

I have a TypeScript interface with two properties (type:string and args:object). The args may have different properties depending on the type. What type definition to I need to apply to args so the compiler/autocomplete will know which properties are allowed for args?

这有点类似于我在 Redux 中使用 Actions 的方式,它有一个 type 和一个 payload 并且在我的 reducer 中,编译器通过 switch 语句知道什么有效载荷包含.但我不能让它与我的对象一起工作.我在这里阅读了一篇很棒的文章 https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/ 但这描述了具有两个相互依赖的 args 的方法的问题,但不是如何让这对两个人起作用同一对象内的属性.

This is somewhat similar to how I use Actions in Redux, which do have a type and a payload and in my reducer the compiler knows by the switch-statement what the payload contains. But I can't get this to work with my object. I have read an excellent article here https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/ but this describes the problem for a method with two args which depend on one another but not how to get this working for two properties within the same object.

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 并将类型设置为检查",编译器/自动完成应该提供 IParametersCheck 的属性.

If I have an IObject and set the type to "check" the compiler/autocomplete should offer the properties for IParametersCheck.

推荐答案

我认为您实际上正在寻找的是一个有区别的联合.IObject 本身应该是一个联合:

I think what you are actually looking for is a discriminated union. IObject should itself be a union:

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
}

你也可以用条件类型来做,但我认为联合解决方案效果更好:

You could also do it with conditional types but I think the union solution works better :

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

这篇关于打字稿:属性的类型依赖于同一对象中的另一个属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆