As an example, say I have a simple function which maps a variadic number of things to an array of objects like { a: value }.
const mapToMyInterface = (...things) => things.map((thing) => ({ a: thing}));
Typescript in not yet able to infer a strong type for the result of this function yet:
const mapToMyInterface = mapToInterface(1, 3, '2'); // inferred type{ a: any }[]
First, I define a type that describes an array mapped to observables:
type MapToMyInterface<T extends any[]> = {
[K in keyof T]: T[K] extends Array<infer U> ? { a: U } : { a: T[K] }
}
Now I update my function:
const mapToMyInterface = <T extends any[]>(...things: T): MapToMyInterface<T> => things.map((thing) => ({ a: thing}));
So far, Typescript is not happy. The return expression of the function is highlighted with the error "TS2322: Type '{ a: any; }[]' is not assignable to type 'MapToMyInterface'"
Obviously, the parameter thing needs to be explicitly typed in the mapping function. But I don't know of a way to say "the nth type", which is what I need.
That is to say, neither marking thing as a T[number] or even doing the following works:
const mapToMyInterface = <T extends any[], K = keyof T>(...things: T): MapToMyInterface<T> => things.map((thing: T[K]) => of(thing));
Is is possible for this to work in Typescript?
EDIT after @jcalz's answer: For posterity, I wanted to post the original motivation for my question, and the solution I was able to get from @jcalz's answer.
I was trying to wrap an RxJs operator, withLatestFrom, to lazily evaluate the observables passed into it (useful when you may be passing in an the result of a function that starts an ongoing subscription somewhere, like store.select does in NgRx).
I was able to successfully assert the return value like so:
export const lazyWithLatestFrom = <T extends Observable<unknown>[], V>(o: () => [...T]) =>
concatMap(value => of(value).pipe(withLatestFrom(...o()))) as OperatorFunction<
V,
[V, ...{ [i in keyof T]: TypeOfObservable<T[i]> }]
>;
Observableandofwhich depends on a third-party library. If your question is dependent on this library, it should probably be tagged as such. If not, you might want to remove the dependence by providing a toy implementation of something similar.Array.prototype.map()is not going to do anything higher-order by itself, but you can certainly give it an appropriate mapped tuple type yourself.ofseems to return typeanymaking this strict return type futile. And also it seems likeofis deprecated.Observableto make the content of my question clear.