You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复TypeScript联合类型Media的属性不存在错误?

问题

从API获取影视数据时,API返回电影和剧集两种不同结构:

  • 剧集包含name、original_name、origin_country、first_air_date字段
  • 电影包含original_title、release_date、title、video字段
    二者还有一些共同属性,因此定义了TypeScript联合类型Media:
export type Media = {
    adult: boolean;
    backdrop_path?: string;
    genre_ids: number[];
    id: number;
    original_language: string;
    overview: string;
    popularity: number;
    poster_path?: string;
    vote_average: number;
    vote_count: number;
} & (
    | {
            original_title: string;
            release_date: string;
            title: string;
            video: boolean;
      }
    | {
            first_air_date: string;
            name: string;
            origin_country: string[];
            original_name: string;
      }
);

但在以下场景使用时,出现类型错误:Property 'original_title' does not exist on type 'Media'和Property 'original_name' does not exist on type 'Media':

...
<View>
    {moviesData.results.map((result: Media) => (
        <Text key={result.id}>{result.original_title}</Text>
    ))}
</View>
<View>
    {showsData.results.map((result: Media) => (
        <Text key={result.id}>{result.original_name}</Text>
    ))}
</View>
...

解决方案

1. 拆分独立类型(推荐)

既然moviesData和showsData分别对应电影和剧集,先拆分出独立的Movie和TVShow类型,再通过联合类型得到Media:

// 定义共同属性
type MediaCommon = {
    adult: boolean;
    backdrop_path?: string;
    genre_ids: number[];
    id: number;
    original_language: string;
    overview: string;
    popularity: number;
    poster_path?: string;
    vote_average: number;
    vote_count: number;
};

// 电影类型
export type Movie = MediaCommon & {
    original_title: string;
    release_date: string;
    title: string;
    video: boolean;
};

// 剧集类型
export type TVShow = MediaCommon & {
    first_air_date: string;
    name: string;
    origin_country: string[];
    original_name: string;
};

// 保留联合类型
export type Media = Movie | TVShow;

之后给数据指定对应类型,错误即可消除:

<View>
    {moviesData.results.map((result: Movie) => (
        <Text key={result.id}>{result.original_title}</Text>
    ))}
</View>
<View>
    {showsData.results.map((result: TVShow) => (
        <Text key={result.id}>{result.original_name}</Text>
    ))}
</View>

2. 使用类型守卫

如果不想拆分类型,可以编写类型守卫函数判断当前Media的具体类型:

function isMovie(media: Media): media is Movie {
    return 'original_title' in media;
}

function isTVShow(media: Media): media is TVShow {
    return 'original_name' in media;
}

使用时先做类型校验:

<View>
    {moviesData.results.map((result: Media) => (
        <Text key={result.id}>{isMovie(result) ? result.original_title : ''}</Text>
    ))}
</View>
<View>
    {showsData.results.map((result: Media) => (
        <Text key={result.id}>{isTVShow(result) ? result.original_name : ''}</Text>
    ))}
</View>

3. 类型断言(不推荐,仅临时应急)

如果能确定当前数据一定是某类型,可以用类型断言强制跳过TypeScript的类型检查:

<View>
    {moviesData.results.map((result: Media) => (
        <Text key={result.id}>{(result as Movie).original_title}</Text>
    ))}
</View>
<View>
    {showsData.results.map((result: Media) => (
        <Text key={result.id}>{(result as TVShow).original_name}</Text>
    ))}
</View>

这种方法会绕过类型校验,若数据结构不符可能引发运行时错误,仅建议临时使用。

内容的提问来源于stack exchange,提问作者Ahmet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:17:21