首页 > 解决方案 > 基于现有打字稿的动态类型

问题描述

对于给定的对象,例如:

class Product {
  constructor(
    public metadata: Metadata,
    public topic: Topic,
    public title = 'empty'
  ) {}
  ...
}

我想创建一个界面:

interface State<T> {
}

这样 TypeScript 可以确保 aproduct: State<Product>具有与 Product 相同的结构,但其匹配的叶级属性是布尔值。所以product应该有一个布尔类型的标题属性。


我查看了映射类型的只读示例,但在这种情况下,我可能需要一个复合:

interface State<T> {
  [p in keyof T]: typeof T[p] === 'object' ? State<T[p]> : boolean;
}

关于如何完成这项工作的任何想法?

标签: typescript

解决方案


你很接近,你的语法是关闭的,你需要使用 atype而不是 a interface,并且typeof T[p] === 'object'写成T[p] extends object

class Metadata {
  constructor(
    public key = 'empty',
    public value = 'empty'
  ) { }
}
class Topic {
  constructor(
    public name = 'empty'
  ) { }
}
class Product {
  constructor(
    public metadata: Metadata[],
    public topic: Topic,
    public title = 'empty'
  ) { }

}

type State<T> = {
  [P in keyof T]: T[P] extends object ? State<T[P]> : boolean
}
let o: State<Product> = {
  title: true,
  topic: {
    name: true
  },
  metadata: [
    { key: true, value: false }
  ]
}

游乐场链接


推荐阅读