能否通过TypeScript函数重载区分字符串字面量与泛型字符串类型?
合并TypeScript列求和函数的类型检查与运行时校验需求
我需要编写一个TypeScript函数,实现键值数组行数据的列求和功能,同时满足以下要求:
- 当传入类型化字符串字面量列名时,函数能自动检测拼写错误或值类型非
number的列; - 当传入泛型字符串类型的动态列名时,函数会在运行时检查列是否存在且值为
number类型。
目前我已经实现了两个独立的函数:
- 第一个函数
columnSumLiteral能准确接受值为number类型的列名字面量,拒绝不符合要求的列名; - 第二个函数
columnSumGeneric能接受任意动态列名,并执行运行时校验。
我希望将这两个函数合并为一个,同时保留对非法字符串字面量列名的类型提示能力。
以下是相关代码及测试示例:
type KeyValue = { [key: string]: unknown }; type NumberFields<Row extends KeyValue> = { [Property in keyof Row as Row[Property] extends number ? Property : never]: number; }; type NumberFieldKey<Row extends KeyValue> = keyof NumberFields<Row>; function columnSumLiteral<Row extends KeyValue>( array: (Row & NumberFields<Row>)[], field: NumberFieldKey<Row> ) { return array.reduce<number>((acc, x) => { return acc + x[field]; }, 0); } function columnSumGeneric<Row extends KeyValue>( array: Row[], field: string ) { return array.reduce<number>((acc, x) => { const value = x[field]; if (typeof value !== 'number') return acc; return acc + value; }, 0); } type Row = { textCol: string; numberCol: number; }; const rows : Row[] = [ { textCol: 'five', numberCol: 5, }, { textCol: 'seven', numberCol: 7, }, { textCol: 'nine', numberCol: 9, }, ]; const numberColGeneric = 'numberCol' as string; const textColGeneric = 'textCol' as string; console.log('能否将两个`columnSum()`变体合并为一个重载函数,并实现预期行为?') console.log('符合预期被接受:', columnSumLiteral(rows, 'numberCol')); console.log('符合预期被拒绝,产生"未定义行为"可接受:', columnSumLiteral(rows, 'textCol')); console.log('被拒绝但应被接受并执行运行时检查:', columnSumLiteral(rows, numberColGeneric)); console.log('被拒绝但应被接受并执行运行时检查:', columnSumLiteral(rows, textColGeneric)); console.log('符合预期被接受:', columnSumGeneric(rows, 'numberCol')); console.log('被接受但应被拒绝:', columnSumGeneric(rows, 'textCol')); console.log('符合预期被接受并执行运行时检查:', columnSumGeneric(rows, numberColGeneric)); console.log('符合预期被接受并执行运行时检查:', columnSumGeneric(rows, textColGeneric));
内容的提问来源于stack exchange,提问作者Tilman Vogel
相关产品推荐
相关产品推荐

