如何根据第一个参数的类型限制第二个参数的类型?
为
calculate函数定义TypeScript类型的方案 我们可以通过类型映射和泛型约束来实现操作类型与参数结构的强关联,确保传入的operation和data始终匹配,同时让TypeScript提供准确的类型校验与提示。
步骤1:定义操作与参数的类型映射
先创建一个类型,将每个操作字符串对应的参数结构一一对应:
type OperationParams = { add: { addend_1: number; addend_2: number }; divide: { dividend: number; divisor: number }; };
步骤2:用泛型约束实现参数关联
提取操作名称的联合类型,再通过泛型让函数的两个参数形成绑定关系:
type Operation = keyof OperationParams; function calculate<T extends Operation>( operation: T, data: OperationParams[T] ): number { if (operation === 'add') { return data.addend_1 + data.addend_2; } else if (operation === 'divide') { return data.dividend / data.divisor; } // 兜底处理,避免TypeScript报错 throw new Error(`Unsupported operation: ${operation}`); }
验证类型约束效果
现在调用函数时,TypeScript会自动校验参数匹配:
// ✅ 合法调用,类型完全匹配 calculate('add', { addend_1: 1, addend_2: 2 }); calculate('divide', { dividend: 42, divisor: 7 }); // ❌ 类型报错:传add时不能使用divide的参数结构 calculate('add', { dividend: 42, divisor: 7 }); // ❌ 类型报错:divide参数缺少divisor字段 calculate('divide', { dividend: 42 });
可选方案:函数重载
如果更偏好显式的签名声明,也可以用函数重载实现同样的效果:
function calculate(operation: 'add', data: { addend_1: number; addend_2: number }): number; function calculate(operation: 'divide', data: { dividend: number; divisor: number }): number; function calculate(operation: string, data: any): number { if (operation === 'add') { return data.addend_1 + data.addend_2; } else if (operation === 'divide') { return data.dividend / data.divisor; } throw new Error(`Unsupported operation: ${operation}`); }
这种方式适合操作类型较少的场景,签名直观易懂;而泛型映射的方式更易扩展,新增操作时只需在OperationParams中添加对应结构即可。
内容的提问来源于stack exchange,提问作者Evgeniy Pozdnyakov
相关产品推荐
相关产品推荐

