0

I have a Datum<T> type where T may be either a number or a string. Datums are collected as arrays in an object. I have an aggregateDatums function that takes object, key name with Datums array, and returns a datum as well.

export interface Datum<T extends string | number> {
    key: T;
    count: number;
}

const aggregateDatums = <
    TKey extends string | number,
    T extends { [k in K]: Datum<TKey>[] },
    K extends keyof T
    >(data: T, key: K): Datum<TKey>[] => {
    return [];
};

const data = {
    numeric: [{key: 1, count: 1}, {key: 2, count: 2}],
    text: [{key: 'a', count: 1}, {key: 'b', count: 2}],
};

const aggregated = {
    numeric: aggregateDatums(data, 'numeric'), // should be type Datum<number>[], but is Datum<string | number>[]
    text: aggregateDatums(data, 'text'), // should be type Datum<string>[], but is Datum<string | number>[]
};

TypeScript playground

Because I pass an object and a key that holds array, not an array of Datums directly, the result is typed Datum<string | number>[]. My goal is the type to correspond to the type of Datums in source array, so Datum<string>[] or Datum<number>[]. Any tips on how can I achieve this?


The example is simplified to show the problem only. But if I overengineered typings that can be done simpler, please let me know.

Also, I would be grateful if someone can recommend resources on advanced typings in TypeScript. Unfortunately, most resources is about types like Partial<T> etc, while I know you can do advanced magic with types :-)

1 Answer 1

1
const aggregateDatums = <
    T extends { [k in K]: Datum<string | number>[] },
    K extends keyof T
    >(data: T, key: K): T[K] extends Datum<infer P>[] ? Datum<P>[] : never => {
    throw 'implemented';
};
Sign up to request clarification or add additional context in comments.

3 Comments

Please write at least few words what you have changed)
The type itself works, but it throws error for any return value, even if it's as simple as return [] or return data[key].
It depends on how your implementation will be and what you want to achieve. I would make it return merely T[K] for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.