1

This is what i am trying to accomplish but for an object with generics. Is there a `valueof` similar to `keyof` in TypeScript?.

// Something on this lines. I know this is not supported but i am trying to convey the idea here.

type payload<T> = <K extends keyof T>{prop: K, value: T[K]};

const someObj = {a: string, b: number};

type someObjType = payload<someObj>;

const someObjPayload: someObjType = { prop: 'a', value: 'some string'} // should work.

const someObjPayload: someObjType = { prop: 'a', value: 200 } // should throw an error.
Amol Gupta
  • 2,054
  • 1
  • 14
  • 29

2 Answers2

1

Since only number and string are allowed in TypeScript, it might be simpler to just write everything two times - leaving your type parameter K out

type stringKeyPayload<T> = {prop: string, value: T}
type numberKeyPayload<T> = {prop: number, value: T}
Nigel Nop
  • 180
  • 1
  • 6
  • Sorry for the lame answer :D I recently had a similar problem and came up with that solution – Nigel Nop Sep 26 '18 at 07:54
  • 1
    The problem with your answer is that `value` should be a type taht is a property type of `T` not `T` (ie `T[keyof T]`) And the problem OP wants to solve is to ensure the value is of the same type as the property specified by `K` .. – Titian Cernicova-Dragomir Sep 26 '18 at 08:00
  • Ah, I see. Thanks for pointing that out. @Titian's answer looks way better – Nigel Nop Sep 26 '18 at 08:08
1

Unfortunately typescript doesn't allow partial inference for variables. If you want to ensure that the value is of the same type as the property specified by key you will need o use a helper function to get the apropriate inference behavior:

type payload<T, K extends keyof T> = {prop: K, value: T[K]};

let someObj!: {a: string, b: number};

function getProp<K extends keyof typeof someObj>(o: payload<typeof someObj, K>) {
  return o
}

const someObjPayload = getProp({ prop: 'a', value: 'some string'}) // ok of type payload<{ a: string; b: number; }, "a">

const someObjPayload2= getProp({prop: 'a', value: 100}) // error
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357