【问题标题】:dynamic type based on existing in typescript基于现有打字稿的动态类型
【发布时间】:2019-04-24 19:50:44
【问题描述】:

对于给定的对象,例如:

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

我要创建一个界面:

interface State<T> {
}

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


我查看了mapped-types 的只读示例,但在这种情况下,我可能需要一个组合:

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

对如何实现这项工作有任何想法吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    你很接近,你的语法是关闭的,你需要使用type而不是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 }
      ]
    }
    

    Playground link

    【讨论】:

    • 听起来很有希望,我去看看
    • 由于某种原因在扩展关键字处编译中断:TS1005:';'预计。
    • @RobyRodriguez 你用的是什么版本的 TS?代码在playground 3.4上测试过,我加个链接
    • "typescript": "~2.7.2" :(
    • @RobyRodriguez 是的 .. 那行不通,你可能会在 2.8 上得到一些工作(数组将是一个问题,我相信在 3.2 或 3.1 中添加了映射类型中的正确数组处理)但 2.7 确实没有条件类型
    【解决方案2】:

    使用类型而不是接口:

    type State<T> = { [P in keyof T]: boolean };
    

    【讨论】:

    • 虽然不是 100% 清楚,但我认为 OP 想要映射一个嵌套结构,其原始属性为 boolean
    • 哦,那我误会了。 “......但它匹配的叶级属性是布尔值。”,你是对的。那么他有你的答案。 :)
    猜你喜欢
    • 2022-12-19
    • 1970-01-01
    • 2021-09-05
    • 2020-01-23
    • 2020-04-02
    • 2020-03-09
    • 1970-01-01
    • 2021-11-25
    • 2021-03-10
    相关资源
    最近更新 更多