在运行时验证打字稿联合类型

问题描述 投票:0回答:1

背景:

type Animal = 'Lion' | 'Cat' | 'Mouse' | 'Sheep';
type Feline = 'Lion' | 'Cat' ;

type AnimalInfo = {
    Category: Animal;
    Age: number;
} & {
   Category: Feline;
   Age: number;   
   Owner:string;
};

const x: AnimalInfo;
if(x.Category === 'Lion' || x.Category === 'Cat'){
  console.log(x.Owner);
}

我如何确定稍后我将“Tiger”添加到

Animal
类型,无需更改为
if
,或者至少
if
给我一个编译时打字稿错误?

typescript runtime union-types
1个回答
0
投票

我猜你在这里犯了一些错误,例如我认为你想缩小受歧视的联合,但你使用了一个交集,它给了你

Category: Feline
中的
AnimalType
,我想这不是你想要的。

要解决运行时检查,请使用集合,从中提取值作为类型,并使用类型保护(不幸的是,

Set#has()
不会缩小)来检查
AnimalInfo
是否为
Feline

游乐场

type SetValues<T extends Set<unknown>> = T extends Set<infer I> ? I : never;

const felineCategories = new Set(['Lion', 'Cat'] as const); // you add any new types here
const isFeline = (animal: AnimalInfo): animal is Feline => felineCategories.has(animal.Category as FelineCategory);
type FelineCategory = SetValues<typeof felineCategories>;
type AnimalCategory = 'Mouse' | 'Sheep';

type Animal = {
    Category: AnimalCategory;
    Age: number;
}

type Feline = {
   Category: FelineCategory;
   Age: number;   
   Owner:string;
}

type AnimalInfo = Animal | Feline;

declare const x: AnimalInfo;
if(isFeline(x)){
  console.log(x.Owner);
}
© www.soinside.com 2019 - 2024. All rights reserved.