我有一个名为movies
可以采用定义为以下接口的两种形状的形式:
interface BaseMovie {
id: number;
title: string;
}
interface MultiSearchResult extends BaseMovie {
media_type: "movie" | "tv" | "person";
}
我知道当另一个变量时,triggeredSearch
为真,形状将是MultiSearchResult
。形状将是BaseMovie
when triggeredSearch
是假的。
使用它来渲染每个项目时
<ul>
{movies.map((movie, i) => (
<li key={i}>{!triggeredSearch ? movie.title : movie.media_type}</li>
))}
</ul>
我收到以下警告:
属性“media_type”在类型“BaseMovie | ”上不存在多重搜索结果'。
类型“BaseMovie”上不存在属性“media_type”。ts(2339)
有没有办法,除了使用as
关键字(即(movie as MultiSearchResult).media_type
),声明一个movie
is a MultiSearchResult
when triggeredSearch
是真的?
可以找到完整的示例here.
TypeScript 无法根据另一个变量的值缩小一个变量的类型,但它can根据工会成员之一缩小工会类型。所以如果你可以把triggeredSearch
and movies
在相同的数据结构中,您可以使用可区分联合来区分事物:
type Example =
{ triggeredSearch: true, movies: null | MultiSearchResult[] }
|
{ triggeredSearch: false, movies: null | BaseMovie[] };
declare const data: Example;
// Side note: Using thea rray index as the key an anti-pattern if the
// arrays contents ever change, more here:
// https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318
const items = data.triggeredSearch
? data.movies?.map((movie, i) => <li key={i}>{movie.media_type}</li>)
: data.movies?.map((movie, i) => <li key={i}>{movie.title}</li>);
const result = <ul>{items}</ul>;
游乐场链接
如果不能,您可以使用类型断言函数而不是as
,如果断言为 false,它的优点是会给出运行时错误:
function assertMultiSearchResult(movie: BaseMovie): asserts movie is MultiSearchResult {
if (!("media_type" in movie)) {
throw new Error(`Given 'movie' is not a 'MultiSearchResult');
}
}
Then:
<ul>
{movies?.map((movie, i) => {
let content: string;
if (triggeredSerach) {
assertMultiSearchResult(movie);
content = movie.media_type;
} else {
content = movie.title;
}
return <li key={i}>{content}</li>;
})}
</ul>
更冗长,但也更安全。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)