Issue
I am trying to create a function that will invert the provided object.
For instance, I have this object
{
 a: "aee",
 b: "bee",
 c: "cee"
}
I want to make it
{
 aee: "a",
 bee: "b",
 cee: "c"
}
Using a function as follows:
mapSelf(myObject)
The logic in JavaScript is straight forward:
function mapSelf(object) {
  const result = {};
  for (const [key, value] of Object.entries(object)) {
    result[value] = key;
  }
  return result;
}
const test = mapSelf({
  a: 'aee',
  b: 'bee',
  c: 'cee',
})
console.log(test)
// {
//   "aee": "a",
//   "bee": "b",
//   "cee": "c"
// }
Doing this in typescript almost works!
function mapSelf<const T extends Record<string, string>>(
  object: T
): Record<T[keyof T], keyof T> {
  const result: any = {}
  for (const [key, value] of Object.entries(object)) {
    result[value] = key
  }
  return result
}
const test = mapSelf({
  a: 'aee',
  b: 'bee',
  c: 'cee',
})
However, I am losing the relation between the keys and their values in the final output.
When I try to hover over H
const H = test.aee
I get H inferred as
const H: "a" | "b" | "c"
I want H to be equal to its corresponding key, in this case, H should be inferred as "a"
Solution
The type you're looking for is the key-remapped type {[K in keyof T as T[K]]: K}.  That lets you choose a new key for each property K of T:
function mapSelf<const T extends Record<string, string>>(
    object: T
): { [K in keyof T as T[K]]: K } {
    const result: any = {}
    for (const [key, value] of Object.entries(object)) {
        result[value] = key
    }
    return result
}
const test = mapSelf({
    a: 'aee',
    b: 'bee',
    c: 'cee',
})
/* const test: {
    readonly aee: "a";
    readonly bee: "b";
    readonly cee: "c";
} */
                            Answered By - jcalz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.