TypeScript 映射类型:带嵌套的标记类型 [英] TypeScript mapped types: Flag type with nesting

查看:23
本文介绍了TypeScript 映射类型:带嵌套的标记类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TypeScript 中是否有一种方法可以创建 高级类型 文档?

Is there a way in TypeScript to create a nested version of a Flags type mentioned in Advanced types documentation?

效果很好:

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 类型,它可以像这样处理嵌套对象,该怎么办?

But what if I wanted to create let's say a NestedFlags type that would be able to handle nested objects like this?

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] 创建一个 NestedFlags 类型:boolean |NestedFlags.该解决方案运行良好,除了它允许我创建一个对象,例如.more: false 这对我来说是不受欢迎的.

I am able to create a NestedFlags type with [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.

谢谢!

推荐答案

您可能想要 映射条件类型 将从 TypeScript v2.8 开始提供,将于本月某个时间(2018 年 3 月)发布.您现在可以通过 typescript@next 使用它.这是我如何实施它的第一次尝试:

You probably want mapped conditional types, which will be available starting in TypeScript v2.8, to be released sometime this month (March 2018). You can use it now with 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
}

上一行使用了条件类型三元类型语法.这意味着:对于 T 中的每个键,NestedFlags 的属性类型将取决于原始属性是否为对象类型.如果原始属性不是对象类型,则对应的属性将为布尔值.如果原始属性一个对象类型,那么相应的属性将是一个应用于该对象类型的NestedFlags<>.

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. 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.

这为您提供了以下行为:

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 抱怨 badActiveNestedColors,说 more 不应该是 boolean.

TypeScript complains about badActiveNestedColors, saying that more should not be a boolean.

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

Hope that helps. Good luck!

这篇关于TypeScript 映射类型:带嵌套的标记类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆