Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Match pair for keyof and valueof an interface

Tags:

typescript

I have an interface like this:

interface ISession {
    emailAddress: string;
    me: IUser | null;
    groups: IGroup[] | null;
}

I want to create a an object with this pseudo-code:

type SetAction = {
    type: typeof SET,
    key: K in keyof ISession,
    value: V in valueof ISession
};

The problem with this pseudocode is it does not ensure that the value type matches the value of ISession[k].

Is this possible in TS?

A similar problem I had to this, this is not apart of the question, but to help others maybe think, because i feel the solution would be the same. I need to write a function function set(key, value). Where the key and value are of the approprate matching pair.

like image 735
Noitidart Avatar asked Oct 29 '25 07:10

Noitidart


1 Answers

You can create such a type but what you want to do is create a union of all possible key/value combinations. So the type we want to create is:

type SetAction  = 
    { type: typeof SET, key: 'emailAddress', value: string; } |
    { type: typeof SET, key: 'me', value:  IUser | null; } |
    { type: typeof SET, key: 'groups', value: IGroup[] | null; }

We can do this by using a distributive conditional type

type SetAction = keyof ISession extends infer K ? // introduce type parameter 
    K extends keyof ISession ? // distribute over the type parameter 
        { type: typeof SET, key: K, value: ISession[K]; } // The type that we construct for each K
    : never: never

Or a perfhaps simpler to understand version using mapped types (the result is the same):

type SetAction = {
    [K in keyof ISession]-?: { type: typeof SET, key: K, value: ISession[K]; } 
}[keyof ISession]
like image 149
Titian Cernicova-Dragomir Avatar answered Oct 31 '25 02: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!