Reputation: 91
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
Upvotes: 5
Views: 719
Reputation: 74530
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
Upvotes: 2