TypeScript映射类型:带嵌套的标记类型

时间:2018-03-06 19:13:11

标签: typescript mapped-types

在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
  }
}

我可以使用NestedFlags创建[P in keyof T]: boolean | NestedFlags<T[P]>类型。该解决方案效果很好,除了它允许我创建一个对象,例如。 more: false这在我的案例中是不受欢迎的。

谢谢!

1 个答案:

答案 0 :(得分:4)

你可能想要{Type 3}},它将从TypeScript v2.8开始提供,将在本月(2018年3月)的某个时候发布。您现在可以使用typescript@next。这是我实现它的第一步:

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

以上行使用mapped conditional types三元类型语法。这意味着:对于T中的每个键,NestedFlags<T>的属性类型将取决于原始属性是否为对象类型。如果原始属性不是对象类型,则相应的属性将为boolean。如果原始属性对象类型,则相应的属性将是NestedFlags<>应用于该对象类型。

这会给您以下行为:

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

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

相关问题