TypeScript 映射类型:带嵌套的标志类型
TypeScript mapped types: Flag type with nesting
在 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<T[P]>
创建一个 NestedFlags
类型。该解决方案效果很好,除了它允许我用例如创建一个对象。 more: false
这对我来说是不可取的。
谢谢!
您可能希望 mapped conditional types 在本月某个时候(2018 年 3 月)发布,它将从 TypeScript v2.8 开始可用。您现在可以使用 typescript@next
。这是我如何实现它的第一枪:
type NestedFlags<T> = {
[K in keyof T]: T[K] extends object ? NestedFlags<T[K]> : boolean
}
上面一行使用了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
。
希望对您有所帮助。祝你好运!
在 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<T[P]>
创建一个 NestedFlags
类型。该解决方案效果很好,除了它允许我用例如创建一个对象。 more: false
这对我来说是不可取的。
谢谢!
您可能希望 mapped conditional types 在本月某个时候(2018 年 3 月)发布,它将从 TypeScript v2.8 开始可用。您现在可以使用 typescript@next
。这是我如何实现它的第一枪:
type NestedFlags<T> = {
[K in keyof T]: T[K] extends object ? NestedFlags<T[K]> : boolean
}
上面一行使用了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
。
希望对您有所帮助。祝你好运!