首页 > 解决方案 > 打字稿:将联合类型映射到单一类型

问题描述

我正在尝试缩小(通过推理)我想要从此数组过滤器中删除的类型,但它给了我一个 TypeError: 'Item' is missing the following properties

type ItemList = (Item | ItemGroup )[];
type ItemGroup = {
  name: string;
  items: Item[];
}
type Item = {
  key: string;
  label: string;
}

const list: ItemList = [
   {
      key: 'key',
      label: 'label'
   },
   {
      name: 'name',
      items: [
        {
          key: 'key1',
          label: 'label2'
        },
        {
          key: 'key3',
          label: 'label4'
        },
      ]
   }
]

const groups: ItemGroup[] = list.filter( l => 'name' in l )
      ^^^^^^
// Type '(Item | ItemGroup)[]' is not assignable to type 'ItemGroup[]'.
//   Type 'Item | ItemGroup' is not assignable to type 'ItemGroup'.
//     Type 'Item' is missing the following properties from type 'ItemGroup': name, items ts(2322)

有任何想法吗?

标签: typescripttypestypescript-typingsunion-types

解决方案


您有一个包含ItemItemGroup元素的数组。您想将此数组过滤为仅是 的元素ItemGroup,并且您希望打字稿了解您已过滤列表并知道返回的类型是ItemGroup[]

如何实现这一点是购买将过滤器l => 'name' in l变成自己的类型保护功能。返回类型value is ItemGroup告诉打字稿“当且仅当这是真的,值是 ItemGroup 类型”。

const isItemGroup = (value: Item | ItemGroup): value is ItemGroup => 'name' in value;

const groups: ItemGroup[] = list.filter( isItemGroup );

通过使用类型保护,打字稿可以理解的含义list.filter并且你的错误消失了。

游乐场链接


推荐阅读