如何为React函数式组件添加泛型以适配多类型场景
正确实现React泛型组件适配string/number类型的方案
核心思路
给组件定义泛型Props,让外部调用时可以指定具体的类型(string或number),同时让组件内部逻辑能正确推断和使用该类型,避免联合类型带来的类型模糊问题。
具体实现代码
1. 定义泛型组件
import React from 'react'; // 定义泛型Props,T约束为string | number的子集 type TestComponentProps<T extends string | number> = { options: T[]; value: T; onChange: (value: T) => void; }; // 声明泛型函数组件 const TestComponent = <T extends string | number>({ options, value, onChange }: TestComponentProps<T>) => { return ( <div> {options.map((option) => ( <button key={option.toString()} // 用toString避免number作为key的警告 onClick={() => onChange(option)} style={{ backgroundColor: option === value ? '#165DFF' : 'transparent', color: option === value ? 'white' : 'black', margin: '0 4px', padding: '4px 8px', border: '1px solid #ccc', borderRadius: '4px' }} > {option} </button> ))} </div> ); }; export default TestComponent;
2. 外部调用示例
// 手动指定string类型 <TestComponent<string> options={['apple', 'banana', 'orange']} value="apple" onChange={(val) => console.log(val)} /> // 手动指定number类型 <TestComponent<number> options={[1, 2, 3, 4]} value={1} onChange={(val) => console.log(val)} /> // TypeScript自动推断类型,可省略泛型参数 <TestComponent options={['a', 'b', 'c']} value="a" onChange={(val) => console.log(val)} />
为什么联合类型会出问题?
如果直接用string | number作为Option类型,比如:
type BadProps = { options: (string | number)[]; value: string | number; onChange: (value: string | number) => void; };
会出现以下问题:
- 传入全是number的options时,onChange的参数仍会被推断为
string | number,处理时需额外做类型判断 - 组件内部
option === value的比较,TypeScript会认为存在类型不匹配风险(比如string和number比较永远为false) - 外部调用时无法约束value和options的类型一致性,可能出现value是string但options全是number的错误情况
而泛型可以确保options、value、onChange的参数类型完全一致,同时让TypeScript在调用时自动推断或手动指定具体类型,避免上述问题。
内容的提问来源于stack exchange,提问作者marielle
相关产品推荐
相关产品推荐

