When exploring the concept of mapped tuple types in TypeScript, the documentation provides an example:
type MapToPromise<T> = { [K in keyof T]: Promise<T[K]> };
type Coordinate = [number, number]
type PromiseCoordinate = MapToPromise<Coordinate>; // [Promise<number>, Promise<number>]
However, what if the original tuple contains nested tuples, and during the mapping process, I want to extract specific values from those inner tuples?
For example:
// Extracting only the numbers from a tuple with mixed data types
type MessyCoordinate = [
[string, number],
[string, number]
]
One might expect to achieve this using the following approach:
type Clean<T extends [string, number]> = T[1]
// Why doesn't this work?
type MapToClean<T> = { [K in keyof T]: Clean<T[K]> }
type CleanCoordinate = MapToClean<MessyCoordinate>; // [number, number]
However, this results in the following compiler error:
Type 'T[K]' does not satisfy the constraint '[string, number]'.
Type 'T[keyof T]' is not assignable to type '[string, number]'.
Type 'T[string] | T[number] | T[symbol]' is not assignable to type '[string, number]'.
Type 'T[string]' is not assignable to type '[string, number]'.(2344)
Adding additional constraints or removing the utility type Clean
do not seem to resolve the issue:
type MapToClean2<T extends [string, number][]> = { [K in keyof T]: Clean<T[K]> }
// Why doesn't this work?
type MapToClean<T> = { [K in keyof T]: T[K][1] }
// Type '1' cannot be used to index type 'T[K]'.
type CleanCoordinate = MapToClean<MessyCoordinate>; // [number, number]
The question arises whether the expectation of extracting values from nested tuples within the mapping process is flawed, or if there is a specific syntax that needs to be applied to achieve this desired outcome.