I want to implement a generic sum
method via Array.prototype.reduce
that sums up a specific numeric property of an entity.
sum
should accept two arguments:
- a generic entity type E
- one of its properties restricted to a
number
return value
My attempt was to use conditional and mapped types here :
Type definitions:
type MeasureableEntityPropNames<E> =
{ [K in keyof E]: E[K] extends number ? K : never }[keyof E];
type MeasurableEntity<E> = Pick<E, MeasureableEntityPropNames<E>>;
type MyEntity = {
p1: number,
p2: string,
p3: Date,
p4: number
};
data:
let entities: MyEntity[] = [
{ p1: 1, p2: "str", p3: new Date(), p4: 3 },
{ p1: 2, p2: "str2", p3: new Date(), p4: 1 }
]
sum method and invocation:
const sum = <E>(elements: MeasurableEntity<E>[], prop: keyof MeasurableEntity<E>) =>
elements.reduce((acc: number, cur: MeasurableEntity<E>) => {
return acc + cur[prop]; // ERROR
}, 0);
sum<MyEntity>(entities, "p1");
Error:
Operator '+' cannot be applied to types 'number' and 'Pick[{ [K in keyof E]: E[K] extends number ? K : never; }[keyof E]]'.
Is there something wrong with the type definitions or can't typescript infer that cur[prop]
is of type number
? What is to change here?
Greetings
(Typescript 3.0.1)