gpt4 book ai didi

Typescript Sum Pluck 类型

转载 作者:搜寻专家 更新时间:2023-10-30 21:21:00 26 4
gpt4 key购买 nike

我正在尝试实现一个 sumPluck 函数。它将允许调用者指定属于数组中对象的数字类型的属性,然后对它们求和。

例子:

type A = { prop: number }

const arr: A[] = [{prop: 1}, {prop: 2}];

pluckSum("prop", arr); // 3

我知道如何键入一个 pluck,但我似乎无法让我的类型认识到它实际上只处理数字属性。这是我的:

type PropertiesOfTypeNames<T, U> = { [K in keyof T]: T[K] extends U ? K : never }[keyof T];
type PropertiesOfType<T, U> = Pick<T, PropertiesOfTypeNames<T, U>>;

type NumberProperties<T> = PropertiesOfType<T, number>;

const pluckSum = <T, K extends keyof NumberProperties<T>>(arr: T[], k: K) =>
pipe(
arr,
R.map(v => v[k]),
R.sum
);

我在 map 下收到一条错误消息:Type 'T[string]' is not assignable to type 'number

因此映射类型似乎并没有表明 v[k] 是一个数字属性。我一定是在这里做错了什么。

最佳答案

不管 Typescript,我想向您展示一种循环融合的替代方法,即消除冗余数组遍历。我通过 (b -> c) -> (a -> c -> d) -> a -> b -> d 类型的有点非正统的组合器获得了循环融合(在 Hindley-Milner 符号中),我称之为 contramap2nd,因为它对二元函数的第二个参数进行了对映。

长话短说

// (b -> c) -> (a -> c -> d) -> a -> b -> d
const contramap2nd = g => f => x => y =>
f(x) (g(y));

const arrFold = f => init => xs =>
xs.reduce((acc, x) => f(acc) (x), init);

const add = x => y => x + y;
const prop = k => o => o[k];

const pluckSum = k =>
arrFold(
contramap2nd(
prop(k))
(add)) (0);

console.log(
pluckSum("foo") ([{foo: 1}, {foo: 2}, {foo: 3}]));

当然,如果您不喜欢 contramap2nd,您可以手动对 add 的第二个参数进行对映。

请注意,您可以通过 mapcontramap 等获得循环融合。

关于Typescript Sum Pluck 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57012247/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com