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
相关产品推荐
相关产品推荐

