I have a type like below:

type Entity =
  | {
      type: 'user' | 'person';
      id: string;
    }
  | {
      type: 'animal';
      id: number;
    };

Now I want to extract the types from it:

type Animal = Extract<Entity, {type: 'animal'}> - works perfectly (returns { type: 'animal'; id: number; });

type User = Extract<Entity, {type: 'user'}> - returns never.

How can I make it return { type: 'user'; id: string; } ?

推荐答案

The provided documenation for Extract<T, U> says:

Extract from T those types that are assignable to U

And { type: 'user' | 'person', id: string } is not assignable to { type: 'user' }

declare const entity: Entity
const user: { type: 'user' } = entity
/*
Type 'Entity' is not assignable to type '{ type: "user"; }'.
  Type '{ type: "user" | "person"; id: string; }' is not assignable to type '{ type: "user"; }'.
    Types of property 'type' are incompatible.
      Type '"user" | "person"' is not assignable to type '"user"'.
        Type '"person"' is not assignable to type '"user"'.(2322)
*/

Which means you cannot use Extract to do this.


But what you can do is use an intersection (&), which will trim away any union members that cannot be matched by that discriminant.

type User = Entity & { type: 'user' }

const user: User = { type: 'user', id: 'abc' }
user.id // type: string

See Playground

Typescript相关问答推荐

了解TS类型参数列表中的分配

typescribe不能使用值来索引对象类型,该对象类型满足具有该值的另一个类型'

基于平台的重定向,Angular 为16

打印脚本中的动态函数重载

TS2339:类型{}上不存在属性消息

TypeScrip:从对象中提取和处理特定类型的键

如何使这种一对一关系在旧表上起作用?

为什么发送空字段?

如何创建内部和外部组件都作为props 传入的包装器组件?

创建一个函数,该函数返回一个行为方式与传入函数相同的函数

必需的输入()参数仍然发出&没有初始值设定项&q;错误

设置不允许相同类型的多个参数的线性规则

在TS泛型和记录类型映射方面有问题

TypeScript:如何使用泛型和子类型创建泛型默认函数?

Angular另一个组件的nativeelement未定义

元组解释

使用受保护的路由和入门来响应路由

在Nestjs中,向模块提供抽象类无法正常工作

const 使用条件类型时,通用类型参数不会推断为 const

设置 --noImplicitAny 时,Typescript 编译器未标记返回 Any 的函数