Matt Thomas
Matt Thomas

Reputation: 1115

Generic array to return typed indexes

Might be a bad question or not even possible but I've been banging my head against it for awhile and cant figure it out. Thanks in advance!

The T generic creates a join type:

const arrayToArray = <T>(values: T[]) => values;

When I use the function:

const result = arrayToArray([1, 'hi', 3]);

It creates the type:

const result: (string | number)[]

I'm looking for it to create:

const result: [number, string, number]

I'm hoping for 'one' and 'three' to return a type error because they aren't numbers.

const useResultType: typeof result = ['one', 'two', 'three'];

Upvotes: 2

Views: 245

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249716

You want to get tuples inferred from the array literal, there are two ways to convince the compiler to do this:

Using tuples in rest parameters. This removed the array literal from the call:

const arrayToArray = <T extends any[]>(...values: T) => values;

const result = arrayToArray(1, 'hi', 3); //[number, string, number]

Using an union of tuple and array constraint to hint to the compiler you want a union. This preserves passing the parameter as an array:

const arrayToArray = <T extends [any] | any[]>(values: T) => values;

const result = arrayToArray([1, 'hi', 3]); // [number, string, number]

Or if you want a readonly tuple in 3.4 (unreleased yet) you can directly use an as const assertion:

const result = [1, 'hi', 3]  as const; // readonly [number, string, number]

Upvotes: 4

Related Questions