Reputation: 28870
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
Reputation: 33091
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)
If you are interested in tuple manipulations, you can check my blog
Upvotes: 1