[英]TypeScript mapped types: Flag type with nesting
Is there a way in TypeScript to create a nested version of a Flags
type mentioned in Advanced types documentation? TypeScript中是否可以创建高级类型文档中提到的
Flags
类型的嵌套版本?
This works well: 这很好用:
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
}
But what if I wanted to create let's say a NestedFlags
type that would be able to handle nested objects like this? 但是,如果我想创建一个
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
}
}
I am able to create a NestedFlags
type with [P in keyof T]: boolean | NestedFlags<T[P]>
我可以使用
[P in keyof T]: boolean | NestedFlags<T[P]>
创建NestedFlags
类型[P in keyof T]: boolean | NestedFlags<T[P]>
[P in keyof T]: boolean | NestedFlags<T[P]>
. [P in keyof T]: boolean | NestedFlags<T[P]>
。 That solution works well except the fact that it allows me to create an object with eg. 该解决方案效果很好,除了它允许我使用例如创建对象。
more: false
which is undesirable in my case. more: false
,这对我来说是不可取的。
Thank you! 谢谢!
You probably want mapped conditional types , which will be available starting in TypeScript v2.8, to be released sometime this month (March 2018). 您可能希望映射的条件类型 (将从TypeScript v2.8开始提供)在本月的某个时候(2018年3月)发布。 You can use it now with
typescript@next
. 您现在可以通过
typescript@next
使用它。 Here's a first shot at how I'd implement it: 这是我如何实现的第一枪:
type NestedFlags<T> = {
[K in keyof T]: T[K] extends object ? NestedFlags<T[K]> : boolean
}
The above line uses the conditional types ternary type syntax. 上一行使用条件类型三元类型语法。 It means: for every key in
T
, the property type for NestedFlags<T>
will depend on whether the original property is an object type or not. 这意味着:对于
T
每个键, NestedFlags<T>
的属性类型将取决于原始属性是否为对象类型。 If the original property is not an object type, the corresponding property will be boolean. 如果原始属性不是对象类型,则对应的属性将为布尔值。 If the original property is an object type, then the corresponding property will be a
NestedFlags<>
applied to that object type. 如果原始属性是对象类型,则对应的属性将是应用于该对象类型的
NestedFlags<>
。
This gives you the following behavior: 这使您具有以下行为:
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 complains about badActiveNestedColors
, saying that more
should not be a boolean
. TypeScript抱怨
badActiveNestedColors
,说more
不应该是boolean
。
Hope that helps. 希望能有所帮助。 Good luck!
祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.