3

Given an object of type:

type Key2Value = {
  foo: "bar"
  voo: "doo"
}

Provided that the values of this type are always string type, how to construct a utility type ReverseMap<T> that reverse maps the key-value pairs to value-key pairs?

type Value2Key = ReverseMap<Key2Value>
// yields:
type Value2Key = {
  bar: "foo"
  doo: "voo"
}
hackape
  • 18,643
  • 2
  • 29
  • 57
  • Post to document an application of the [answer](https://stackoverflow.com/questions/55208690/combine-two-types-into-an-interface-elegantly-in-typescript) by jcalz. – hackape Mar 20 '20 at 04:15

1 Answers1

5
type Key2Value = {
  foo: "bar"
  voo: "doo"
}

type ReverseMap<T extends Record<keyof T, keyof any>> = {
    [P in T[keyof T]]: {
        [K in keyof T]: T[K] extends P ? K : never
    }[keyof T]
}

type Value2Key = ReverseMap<Key2Value>

Playground

hackape
  • 18,643
  • 2
  • 29
  • 57
  • Incase people are looking for extracting values from the Type, please check https://stackoverflow.com/a/65210846/5519365 – Akash Babu Dec 09 '20 at 04:52
  • A minor comment to the "keyof any", I explicitly wanted to remove it, so you can replace it with T[keyof T] to avoid using the any keyword. – ExoMemphiz Jan 31 '21 at 21:37
  • @ExoMemphiz `keyof any` intents to hint TS that the “value” is gonna be used as “key”. Semantically it cannot be replaced with `T[keyof T]`, latter places zero constraint on the value part. However we need at least the constraint that value *could* be used as key. – hackape Mar 31 '22 at 17:00
  • Also, I dono since when ppl start to witch-hunt `any` type. Geez, `any` is a totally valid and useful type! And this answer is the exact example where you *should* use `any`. Do not apply “rules” blindly, try understand the reason behind those rules. – hackape Mar 31 '22 at 17:05