Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type declaration removing "Array" around types without losing names

I'm working on a project with a friend and we wanted to create a type where the type has the first value of the key in an interface, and if they match the rest should match the parameters of the function associated.

export default interface ClientToServerEvents {
    'authenticate': (token: string) => void;
    'update-title': (title: string, annoteId: string) => void;
}
type Partial<T> = { [P in keyof T]: [P, Parameters<T[P]>]; };
type ClientToServerEventsType = ValueOf<Partial<ClientToServerEvents>>;

This is what we have got so far which results in a type that looks like:

type ClientToServerEventsType = ["authenticate", string] | ["update-title", string, string]

This is almost what we want, but we would want the type to keep the names of the parameters as well, and not just be string. What we want is:

type ClientToServerEventsType = ["authenticate", token: string] | ["update-title", title: string, annoteId: string]

We have been at it for an hour and cannot find anything. Thank you!

like image 247
Esaias Cronelius Avatar asked Oct 15 '25 04:10

Esaias Cronelius


1 Answers

Tuple elements must all either be named or all not named. Since your tuple does not have a name for the first element, all the other names will be erased.

If you name the first element, you will see the names are preserved:

type AllParams<T extends Record<keyof T, (...a: any)=> any>> = { 
  [P in keyof T]: [name: P, ...rest: Parameters<T[P]>]; 
};
type ClientToServerEventsType = ValueOf<AllParams<ClientToServerEvents>>;
//  [name: "authenticate", token: string] | [name: "update-title", title: string, annoteId: string]

Playground Link

like image 95
Titian Cernicova-Dragomir Avatar answered Oct 19 '25 20:10

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!