TypeScript:正确键入函数以求和多维数组列值
TypeScript: properly typed function to sum multi-dimensional array column values
假设我有以下 sum()
方法来对多维数组列值求和:
export class MathUtils {
static sum(values: Record<string, unknown>[], key: string): number {
return values.reduce((acc, cur) => acc + cur[key], 0);
}
}
现在我想使用 TypeScript 执行以下操作:
key
参数应始终是 values[index]
对象键之一
values[index][key]
必须是 number
类型。它还应该允许以不同方式输入其他属性。
我该怎么做?
- key 参数应该始终是 values[index] 对象键之一
您可以通过使用泛型类型来实现。
static sum<K>(values: Record<K, unknown>[], key: K): number {
- values[index][key] 必须是数字类型。
可以通过Record
的第二个类型参数来指定值的类型
static sum<K>(values: Record<K, number>[], key: K): number {
解决方案:
function sum<O extends Record<T, number>, T extends keyof O>(values: O[], key: T): number {
return values.reduce((acc, cur) => acc + cur[key], 0);
}
- 确保 属性 名称正确。
- 检查是否选择 属性 的类型是数字。允许以不同方式键入其他属性。
测试:
interface ChartItem {
name: string;
value: number;
}
const items: ChartItem[] = [{
name: 'Series #1',
value: 10
}, {
name: 'Series #2',
value: 5
}];
// Works as expected
let total = sum(items, 'value');
// Error: 'foo' doesn't exist in ChartItem
total = sum(items, 'foo');
// Error: Types of property 'name' are incompatible
total = sum(items, 'name');
假设我有以下 sum()
方法来对多维数组列值求和:
export class MathUtils {
static sum(values: Record<string, unknown>[], key: string): number {
return values.reduce((acc, cur) => acc + cur[key], 0);
}
}
现在我想使用 TypeScript 执行以下操作:
key
参数应始终是values[index]
对象键之一values[index][key]
必须是number
类型。它还应该允许以不同方式输入其他属性。
我该怎么做?
- key 参数应该始终是 values[index] 对象键之一
您可以通过使用泛型类型来实现。
static sum<K>(values: Record<K, unknown>[], key: K): number {
- values[index][key] 必须是数字类型。
可以通过Record
static sum<K>(values: Record<K, number>[], key: K): number {
解决方案:
function sum<O extends Record<T, number>, T extends keyof O>(values: O[], key: T): number {
return values.reduce((acc, cur) => acc + cur[key], 0);
}
- 确保 属性 名称正确。
- 检查是否选择 属性 的类型是数字。允许以不同方式键入其他属性。
测试:
interface ChartItem {
name: string;
value: number;
}
const items: ChartItem[] = [{
name: 'Series #1',
value: 10
}, {
name: 'Series #2',
value: 5
}];
// Works as expected
let total = sum(items, 'value');
// Error: 'foo' doesn't exist in ChartItem
total = sum(items, 'foo');
// Error: Types of property 'name' are incompatible
total = sum(items, 'name');