You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 18:55:01