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.
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With