【问题标题】:TypeScript mapped types: Flag type with nestingTypeScript 映射类型:带有嵌套的标志类型
【发布时间】:2018-08-14 18:05:01
【问题描述】:

TypeScript 中有没有办法创建 Advanced types 文档中提到的 Flags 类型的嵌套版本?

这很好用:

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

interface Colors {
  red: string;
  green: string;
  blue: string;
}

const activeColors: Flags<Colors> = {
  red: true,
  green: true,
  blue: false
}

但是,如果我想创建一个能够处理这样的嵌套对象的 NestedFlags 类型呢?

interface NestedColors {
  red: string;
  green: string;
  blue: string;
  more: {
    yellow: string;
    violet: string;
    black: string;
  }
}

const activeNestedColors: NestedFlags<NestedColors> {
  red: true,
  blue: false,
  green: true,
  more: {
    yellow: false,
    violet: true,
    black: true
  }
}

我可以用[P in keyof T]: boolean | NestedFlags&lt;T[P]&gt; 创建一个NestedFlags 类型。该解决方案效果很好,只是它允许我使用例如创建一个对象。 more: false 在我的情况下是不可取的。

谢谢!

【问题讨论】:

    标签: typescript mapped-types


    【解决方案1】:

    您可能希望在本月(2018 年 3 月)的某个时候发布 mapped conditional types,它将从 TypeScript v2.8 开始提供。您现在可以通过typescript@next 使用它。这是我如何实现它的第一个镜头:

    type NestedFlags<T> = {
      [K in keyof T]: T[K] extends object ? NestedFlags<T[K]> : boolean
    }
    

    以上行使用conditional types 三元类型语法。这意味着:对于T 中的每个键,NestedFlags&lt;T&gt; 的属性类型将取决于原始属性是否为对象类型。如果原始属性不是对象类型,则相应的属性将为布尔值。如果原始属性一个对象类型,那么对应的属性将是应用于该对象类型的NestedFlags&lt;&gt;

    这会给你以下行为:

    interface NestedColors {
      red: string;
      green: string;
      blue: string;
      more: {
        yellow: string;
        violet: string;
        black: string;
      }
    }
    
    // okay    
    const activeNestedColors: NestedFlags<NestedColors> = {
      red: true,
      blue: false,
      green: true,
      more: {
        yellow: false,
        violet: true,
        black: true
      }
    }
    
    // error
    const badActiveNestedColors: NestedFlags<NestedColors> = {
      red: true,
      blue: false,
      green: true,
      more: false
    } 
    // Types of property 'more' are incompatible.
    // Type 'boolean' is not assignable to ...
    

    TypeScript 抱怨 badActiveNestedColors,说 more 不应该是 boolean

    希望对您有所帮助。祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-19
      • 2022-06-15
      • 2021-12-11
      • 1970-01-01
      • 2018-02-05
      • 1970-01-01
      相关资源
      最近更新 更多