Type level operations for labelled tuple

646 views Asked by At

I'd like to do something similar to below with labelled tuples and wondering it this posible in TS4 yet

type stringProperties<T extends {}> = {[k in keyof T]: string}

This would mean that I could create a type [foo: string, bar: string, baz:string] from [foo: boolean, bar: number, baz: any]

At the moment I'm missing the way to generically capture the label (its not present in keyof) and not sure how to add another label:type pair to an existing tuple type.

I'm aware of the technique below to prepend to an unlabelled tuple but in this case the label will be set as first.

export type Prepend<E, T extends any[]> =
    ((first: E, ...args: T) => any) extends ((...args: infer U) => any)
    ? U
    : never
1

There are 1 answers

0
ford04 On

You can use mapped tuple types to just change element types. Their labels are preserved:

type T1 = stringProperties<[foo: boolean, bar: number, baz: any]> 
// [foo: string, bar: string, baz: string]

While you cannot directly extract the function parameter names, adding a new labeled element is still possible with TS 4.0 variadic tuple types:

type Prepend<E extends [unknown], A extends any[]> = [...E, ...A]
type Append<E extends [unknown], A extends any[]> = [...A, ...E]
// ... extend to your needs

type T2 = Prepend<[customLabel: string], A> 
// [customLabel: string, foo: boolean, bar: number, baz: any]
type T3 = Append<[customLabel: string], A> 
// [foo: boolean, bar: number, baz: any, customLabel: string]
type T4 = Prepend<[customLabel: string], stringProperties<A>> // or mix it up
// [customLabel: string, foo: string, bar: string, baz: string]
... And later on use types as function parameters:
function foo(...args: T4) {}
// function foo(customLabel: string, foo: string, bar: string, baz: string): void

Playground