React中如何根据valueType为函数参数设置对应TypeScript类型?
优雅实现TypeScript组件根据属性动态指定函数参数类型
我们可以通过类型映射和泛型组件来实现需求,让TypeScript自动根据valueType的取值推断对应参数类型,避免冗余的条件判断和重复类型定义。
步骤1:定义类型映射关系
先创建一个类型,把valueType的取值和对应的参数类型做绑定:
type ValueTypeOne = "One" | "Two" | "Three"; type ValueTypeTwo = "A" | "B" | "C"; // 建立valueType到参数类型的映射 type ValueTypeMap = { one: ValueTypeOne; two: ValueTypeTwo; };
步骤2:泛型化组件
让组件接收泛型参数,约束它是ValueTypeMap的键,TypeScript会自动根据传入的valueType锁定对应的参数类型:
import React from 'react'; // 泛型组件,T被约束为ValueTypeMap的key const TestComponent = <T extends keyof ValueTypeMap>({ valueType }: { valueType: T }) => { // 利用泛型T自动获取对应参数类型 const hello = (value: ValueTypeMap[T]) => { // 根据valueType匹配对应的映射对象,类型断言确保安全 const valueMap = { one: { One: "Axxx", Two: "Bxxxx", Three: "Cxxxx" } as Record<ValueTypeOne, string>, two: { A: "1xxx", B: "2xxxx", C: "3xxxx" } as Record<ValueTypeTwo, string>, }[valueType]; return valueMap[value]; }; return <div>...</div>; };
步骤3:使用时的自动类型约束
调用组件时,TypeScript会根据valueType的取值,自动约束hello函数的参数类型:
// valueType为"one"时,hello参数只能是ValueTypeOne的取值 <TestComponent valueType="one" />; // 合法调用:hello("One");非法调用:hello("A")(会触发类型报错) // valueType为"two"时,hello参数只能是ValueTypeTwo的取值 <TestComponent valueType="two" />; // 合法调用:hello("A");非法调用:hello("One")(会触发类型报错)
额外优化:抽离映射对象
如果映射对象逻辑复杂,可以抽离为单独常量,用satisfies确保类型与ValueTypeMap一致:
const valueMaps = { one: { One: "Axxx", Two: "Bxxxx", Three: "Cxxxx" }, two: { A: "1xxx", B: "2xxxx", C: "3xxxx" }, } as const satisfies { [K in keyof ValueTypeMap]: Record<ValueTypeMap[K], string> }; // 组件内直接使用 const hello = (value: ValueTypeMap[T]) => { return valueMaps[valueType][value]; };
这种实现的优势:
- 类型关联集中清晰,
valueType与参数类型的绑定关系统一维护在ValueTypeMap中 - 依赖泛型自动推断,无需手动重复指定类型
- 类型检查严格,避免传入不符合要求的参数
内容的提问来源于stack exchange,提问作者wilker0725
相关产品推荐
相关产品推荐

