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

TypeScript中如何将判别联合类型成员赋值给期望该联合的泛型

解决React-TypeScript中联合类型泛型赋值错误问题

错误原因

你遇到的类型不兼容问题源于泛型参数的逆变特性:

  • FilterSet<Union> 的 targetField 类型是 keyof (FirstType | SecondType),即两个类型的共有键:"name" | "id"。
  • FilterSet<FirstType> 的 targetField 包含专属键 "specificToFirst",类型范围比前者更宽。TypeScript 禁止将宽类型赋值给窄类型,因为组件预期 targetField 只能是联合类型的共有键,传入专属键会破坏类型安全。

解决方案

将组件改为泛型组件,约束泛型参数为 Union 的子类型,这样既保证 filterSet 只能对应联合类型的成员,又能让 targetField 自动匹配传入类型的所有键:

1. 定义泛型Props

type ComponentPropsType<T extends Union> = {
    filterSet: FilterSet<T>;
};

2. 实现泛型组件

export const Component = <T extends Union>({ filterSet }: ComponentPropsType<T>) => {
    // 组件核心逻辑
    return <div>{/* 渲染内容 */}</div>;
};

3. 合法调用示例

此时传入任意联合类型成员对应的 FilterSet 都不会报错:

// 传入FirstType对应的FilterSet
<Component filterSet={{ targetField: "specificToFirst" }} />

// 传入SecondType对应的FilterSet
<Component filterSet={{ targetField: "specificToSecond" }} />

// 传入共有键对应的FilterSet
<Component filterSet={{ targetField: "name" }} />

4. 组件内部类型区分(可选)

如果需要在组件内部针对不同类型做逻辑区分,可以通过类型守卫自动推导类型:

export const Component = <T extends Union>({ filterSet }: ComponentPropsType<T>) => {
    if (filterSet.targetField === "specificToFirst") {
        // TypeScript自动推断T为FirstType
        console.log("处理FirstType专属逻辑");
    } else if (filterSet.targetField === "specificToSecond") {
        // TypeScript自动推断T为SecondType
        console.log("处理SecondType专属逻辑");
    } else {
        // 处理共有键(name/id)的通用逻辑
        console.log("处理通用逻辑");
    }

    return <div>{/* 渲染内容 */}</div>;
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 03:27:38