如何实现TypeScript函数参数依赖于另一参数的严格类型检查
解决下拉选项格式化函数的TypeScript类型约束问题
首先你原JavaScript代码里有个笔误:option[keyAsName]应该是option[keyAsLabel],先修正这个基础问题。
你的TypeScript代码报错的核心原因是:把keyAsLabel和keyAsValue的类型定义成了T,但它们本质上应该是对象T的键名,也就是keyof T类型。要实现参数间的类型依赖,需要用泛型约束来关联三个参数的类型。
正确的TypeScript实现
// 泛型T表示选项对象的类型,K1和K2分别约束为T的键,且对应值适配下拉选项的label/value需求 const formatOptions = <T, K1 extends keyof T, K2 extends keyof T>( options: T[], keyAsLabel: K1, keyAsValue: K2 ) => { return options.map((option, i) => { return { id: i + 1, label: option[keyAsLabel], // 类型自动推导为T[K1] value: option[keyAsValue], // 类型自动推导为T[K2] } }) }
类型约束说明
<T, K1 extends keyof T, K2 extends keyof T>:T是传入的选项数组中每个对象的类型;K1 extends keyof T确保keyAsLabel必须是T对象上存在的键名,避免传入不存在的属性;K2 extends keyof T同理约束keyAsValue;
- 返回的数组中,每个对象的
label和value类型会自动关联原对象对应属性的类型,实现严格的类型检查。
使用示例
// 定义选项类型 type User = { id: number; name: string; email: string; }; const users: User[] = [ { id: 1, name: "张三", email: "zhangsan@example.com" }, { id: 2, name: "李四", email: "lisi@example.com" }, ]; // 调用时编辑器会自动提示User类型的键名,传入非法键会直接报错 const formattedOptions = formatOptions(users, "name", "id"); // 返回类型:Array<{ id: number; label: string; value: number }>
如果业务需要固定label为字符串、value为数字,可以进一步添加类型断言约束:
const formatOptions = < T, K1 extends keyof T, K2 extends keyof T >( options: T[], keyAsLabel: K1, keyAsValue: K2 ) => { return options.map((option, i) => { return { id: i + 1, label: option[keyAsLabel] as unknown as string, value: option[keyAsValue] as unknown as number, } }) }
内容的提问来源于stack exchange,提问作者Johannes
相关产品推荐
相关产品推荐

