[英]How to create a Typescript type guard for my union type
I have the following Typescript types:我有以下 Typescript 类型:
export type TeaserOne = { __typename: 'TeaserOne' } & TeaserOneItem;
export type TeaserTwo = { __typename: 'TeaserTwo' } & TeaserTwoItem;
export type TeaserThree = { __typename: 'TeaserThree' } & TeaserThreeItem;
export type Teaser = TeaserOne | TeaserTwo | TeaserThree;
export type FilteredTeasers = Exclude<Teaser, TeaserThree >;
export type TeaserItem = TeaserOneItem | TeaserTwoItem | TeaserThreeItem;
For example the item types looks a bit like:
// TeaserOneItem:
export interface TeaserOneItem {
type: string;
id: string;
title: string;
lead?: string;
}
// TeaserTwoItem:
export interface TeaserTwoItem {
type: string;
id: string;
title: string;
duration?: string;
image?: Image;
}
In a certain React component I need to create a Typescript type guard :在某个 React 组件中,我需要创建一个Typescript 类型保护:
const filteredItems = data.items?.filter(
(item) =>
item?.__typename.includes('TeaserOne') || item?.__typename.includes('TeaserTwo')
);
// --> Maybe also I can refactor above with a type guard, but how exactly?
{filteredItems.map((node, index) => {
if (isTeaserOne() // <-- Here I want to use a type guard) {
const teaserOne = node as TeaserOneType;
return (
<TeaserOne
key={teaserOne.id}
title={teaserOne.title}
lead={teaserOne.lead}
/>
);
}
const teaserTwo = node as TeaserTwoType;
return (
<TeaserTwo
key={teaserTwo.id}
title={teaserTwo.title}
image={teaserTwo.image}
/>
);
})}
How do I create a nice and clean type guard function isTeaserOne()
?如何创建一个漂亮干净的类型保护 function
isTeaserOne()
? So far I have:到目前为止我有:
const isTeaserOne = (teaser: TeaserItem): teaser is TeaserOneItem =>
typeof teaser === 'object' && teaser.type.includes('TeaserOne');
But how do I have to use this?但是我该如何使用它呢? Or do I have to refactor above type guard function?
或者我是否必须重构上面的类型保护 function?
In your code isTeaserOne = (teaser: Teaser)
use Teaser class, so have the __typename property, you can use it directly在你的代码
isTeaserOne = (teaser: Teaser)
使用 Teaser class,所以有 __typename 属性,你可以直接使用它
const isTeaserOne = (teaser: Teaser): teaser is TeaserOne => teaser.__typename === 'TeaserOne';
const isTeaserTwo = (teaser: Teaser): teaser is TeaserTwo => teaser.__typename === 'TeaserTwo';
const isTeaserThree = (teaser: Teaser): teaser is TeaserThree => teaser.__typename === 'TeaserThree';
filteredItems.map((node) => {
// here typeof node is Teaser
if (isTeaserOne(node)) {
// here typeof node is TeaserOne
<TeaserOne />
}
if (isTeaserTwo(node)) {
// here typeof node is TeaserTwo
<TeaserTwo />
}
if (isTeaserThree(node)) {
// here typeof node is TeaserThree
<TeaserThree />
}
return "nothing";
})
In fact, is suppose your code is incomplete, beacause in facts you do not need a typeguard here.事实上,假设您的代码不完整,因为实际上您在这里不需要类型保护。 a simple
一个简单的
if (node.__typename === "TeaserOne") {
// here typeof node is TeaserOne
<TeaserOne />
}
Would give the same results.会给出相同的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.