我想有一个打字类型,它只允许除了它的‘Kind’之外的一个属性,而且它会根据‘Kind’键的值而变化.

我知道这或多或少是在重写JSON已经做的事情,但我对此没有任何发言权.

以下方法可以使用,但在这种情况下,我更愿意使用动态类型:

export interface TitleComponent {
  kind: 'title'
  title: {
    text: string
    isSubtitle: boolean
  }
}

export interface TextComponent {
  kind: 'text'
  text: {
    text: string
    isBordered: boolean
  }
}

export interface ImageComponent {
  kind: 'image'
  image: {
    name: string | null
    url: string
    thumbnailUrl: string | null
    altText: string | null
    caption: string | null
  }
}

export type Component = TitleComponent | TextComponent | ImageComponent

可能的组件Bundle 在一起(还有更多,这只是为了简短):


export interface Components {
  title: {
    text: string
    isSubtitle: boolean
  }

  text: {
    text: string
    isBordered: boolean
  }

  image: {
    name: string | null
    url: string
    thumbnailUrl: string | null
    altText: string | null
    caption: string | null
  }
}

我的打字问题(天真的方法不起作用):

type AvailableKinds = string & keyof Components;

export interface Component {
  kind: AvailableKinds;
  this['kind']: Components[this['kind']];
}

用法示例:


const t: Component = {
  kind: 'title',
  title: {
    text: 'test',
    isSubtitle: false
  }
};

这完全可以通过TypeScrip来实现(或者我必须坚持上面的解决方案)吗?

推荐答案

你需要使用交叉点来得到你想要的类型.你不能把东西分散到接口上:

type ComponentFor<P extends keyof Components> = { kind: P } & Record<P, Components[P]>
export type Component = {
    [P in keyof Components]: ComponentFor<P>
}[keyof Components]


const t: Component = {
  kind: 'title',
  title: {
    text: 'test',
    isSubtitle: false
  }
};

Playground Link

Typescript相关问答推荐

类型脚本不会推断键的值类型

使用React处理Websocket数据

对深度对象键/路径进行适当的智能感知和类型判断,作为函数参数,而不会触发递归类型限制器

如何设置绝对路径和相对路径的类型?

使用泛型keyof索引类型以在if-condition内类型推断

如何编写一个类型脚本函数,将一个对象映射(转换)为另一个对象并推断返回类型?

如何按不能保证的功能过滤按键?

类型脚本基于数组作为泛型参数展开类型

参数属性类型定义的REACT-RUTER-DOM中的加载器属性错误

部分更新类型的类型相等

Fp-ts使用任务的最佳方法包装选项

推断从其他类型派生的类型

如何在Typescript 中组合unions ?

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

声明遵循映射类型的接口

如何正确地将元组表格输入到对象数组实用函数(如ZIP)中,避免在TypeScrip 5.2.2中合并所有值

有没有一种更好的方法来存储内存中的数据,而不是在类型脚本中使用数组和基于索引的函数?

如何创建由一个帐户签名但使用另一个帐户支付的Hedera交易

覆盖高阶组件中的 prop 时的泛型推理

使用react+ts通过props传递数据