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

React组件渲染遇TypeScript类型冲突:交集类型被缩减为never

React组件联合类型传参的类型冲突解决

问题原因

你当前的代码里,TypeScript没办法通过findIndex的结果,将传入的mode和对应的组件props类型建立关联。它会把找到的Component的props推断成MovieInfoModeProps | PlaylistInfoModeProps,而data是movieModeDataType | playlistModeDataType,两者交叉后因为image等属性的类型冲突,直接缩减为never,所以触发了类型错误。

解决方案

方案一:给模式数组添加精确类型映射

通过定义模式与组件props的映射关系,让TypeScript能明确每个模式对应的组件和数据类型:

首先修改类型定义文件:

export type movieModeDataType = {
    image: string,
    name: string,
    quality: string,
    rate: string,
    genre: string[],
}
export type playlistModeDataType = {
    name: string,
    image?: never,
    quality?: never,
    rate?: never,
    genre?: never
}

// 定义每个模式对应的组件props类型
type ModeComponentPropsMap = {
    movie: { data: movieModeDataType },
    playlist: { data: playlistModeDataType }
}

// 基于映射生成组件的props类型
export type infoPresenterProps = {
    [K in keyof ModeComponentPropsMap]: {
        mode: K,
        ...ModeComponentPropsMap[K]
    }
}[keyof ModeComponentPropsMap]

然后修改组件文件:

import React from "react";
import { infoPresenterProps, ModeComponentPropsMap } from "types/components/info-presenter/infoPresenter.type";
import MovieInfoMode from "components/info-presenter/modes/movie/MovieInfoMode";
import PlaylistInfoMode from "components/info-presenter/modes/playlist/PlaylistInfoMode";

// 定义模式项的类型
type ModeEntry<K extends keyof ModeComponentPropsMap> = {
    key: K,
    Component: React.ComponentType<ModeComponentPropsMap[K]>
}

const MODES: ModeEntry<keyof ModeComponentPropsMap>[] = [
    { key: "movie", Component: MovieInfoMode },
    { key: "playlist", Component: PlaylistInfoMode }
]

export default function InfoPresenter({ mode, data }: infoPresenterProps) {
    const modeEntry = MODES.find(item => item.key === mode) as ModeEntry<typeof mode>;
    return <modeEntry.Component data={data} />;
}

方案二:用条件判断替代数组查找(更直观)

如果模式数量不多,直接用switch或if判断,TypeScript会自动在每个分支里推断出正确的data类型:

import { infoPresenterProps } from "types/components/info-presenter/infoPresenter.type";
import MovieInfoMode from "components/info-presenter/modes/movie/MovieInfoMode";
import PlaylistInfoMode from "components/info-presenter/modes/playlist/PlaylistInfoMode";

export default function InfoPresenter({ mode, data }: infoPresenterProps) {
    switch(mode) {
        case "movie":
            return <MovieInfoMode data={data} />;
        case "playlist":
            return <PlaylistInfoMode data={data} />;
        default:
            throw new Error(`不支持的模式:${mode}`);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 06:54:33