Lodash Sumby之类的对象的泛型类型 [英] Generic type for something like Lodash sumby

查看:10
本文介绍了Lodash Sumby之类的对象的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何键入一个函数来有效地执行lodash.sumby对键的操作?DefinitelyTyped types for it是松散的,不指定字符串参数需要是集合类型的键。

以下内容似乎很接近,但它没有指定T[key]的类型是数字

function sumByKey<T>(list: T[], key: keyof T) {
  return list.reduce((sum, item) => sum + item[key], 0);
}

因此出现错误

Operator '+' cannot be applied to types 'number' and 'T[keyof T]'.

推荐答案

我不会为数组元素使用泛型类型参数T,而是使用泛型来描述键。

我们不关心列表元素的所有细节。我们需要知道的是,list中的每个元素都是一个对象(包括数组),该对象具有一个值为number的属性T

我们必须确保:

  • keyT
  • T extends PropertyKey
  • listArray
  • list的元素为{ [K in T]: number }类型Record<T, number>
function sumByKey<T extends PropertyKey>(list: { [K in T]: number }[], key: T) {
  return list.reduce((sum, item) => sum + item[key], 0);
}

现在该函数没有错误,因为item[key]必须是number


在以内联方式编写列表时有一些限制。

这很好:

const data = [{x: 30, a: 20}, {x: 50, b: 20}];
const sum = sumByKey(data, 'x');

但这会产生错误:

const sum = sumByKey([{x: 30, a: 20}, {x: 50, b: 20}], 'x');
类型‘{x:number;a:number;}’不可赋值给类型‘{x:number;}’。 对象文本只能指定已知属性,并且类型‘{x:number;}’中不存在‘a’

如果要避免此错误,可以更改list的定义,使其具有属性T: number以及任意数量的其他未知属性。

function sumByKey<T extends PropertyKey>(
    list: ({ [K in T]: number } & { [K in PropertyKey]?: unknown })[],
    key: T
) {
  return list.reduce((sum, item) => sum + item[key], 0);
}

现在两者都可以正常工作,没有错误。

TypeScript Playground Link

这篇关于Lodash Sumby之类的对象的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆