dagda1
dagda1

Reputation: 28870

create string literal type from dyanamic array in typescript

I have this code which works great for a static array using as const

type ScaleKeys<A extends readonly unknown[]> = `${keyof A & `${number}`}x`;

const spacing = [0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4] as const;

type SpaceKeys = ScaleKeys<typeof spacing>; // works great with a static array

const a: SpaceKeys = '0x';

But having to statically declare a large static array is not great.

Is it possible to do this with a dynamic array:

I've tried this:

type ScaleKeys<A extends readonly unknown[]> = `${keyof A & `${number}`}x`;

const b: ReadonlyArray<number> = Array.from({ length: 20 });

type C = ScaleKeys<typeof b> // not sure if this is even possible

Here is a playground with the above.

Upvotes: 1

Views: 238

Answers (1)

If you want dynamicly create tuple, you can use this utility type:

type Tuple<N extends number, Cache extends number[] = []> = Cache['length'] extends N ? Cache : Tuple<N, [...Cache, Cache['length']]>

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
type Result = Tuple<20>

If you want to map it, consider this function:



type Tuple<N extends number, Cache extends number[] = []> = Cache['length'] extends N ? Cache : Tuple<N, [...Cache, Cache['length']]>

type MapTuple<T extends ReadonlyArray<number>> = {
    [Prop in keyof T]: `${Prop & string}x`
}

// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
type Result = Tuple<20>

const tuple = <Length extends number>(length: Length) =>
    new Array(length)
        .fill(0)
        .map((_, index): `${number}x` => `${index}x`) as unknown as MapTuple<Tuple<Length>>

// ["0x", "1x", "2x",... "41x"]
const result = tuple(42)

Playgrund

If you are interested in tuple manipulations, you can check my blog

Upvotes: 1

Related Questions