Home > other >  Can I do this type transformation in TypeScript?
Can I do this type transformation in TypeScript?

Time:03-14

type U = {
  foo: {
    id: '001'
    name: 'alan'
  }
  bar: {
    id: '002'
    name: 'dan'
  }
}

type V = {
  '001': 'alan'
  '002': 'dan'
}

// type Trans<T> = ...
// V === Trans<U>

Sorry I don't know how to name it, but anyone can tell me how to archive that?

I've already been trying for several hours but I can only get

// this is not I want
type V = {
  '001': 'alan' | 'dan'
  '002': 'alan' | 'dan'
}

Thanks!

CodePudding user response:

The easiest way to do this would be with a mapped type and a remapped key (docs):

type V = {[K in keyof U as U[K]['id']]: U[K]['name']}
// V = { "001": "alan"; "002": "dan" }

TypeScript playground

CodePudding user response:

You can do this via mapped types and generics. Here is my solution:

type CollapseKV<T extends Record<PropertyKey, Record<PropertyKey, unknown>>, K extends keyof T[keyof T], V extends keyof T[keyof T]> =
    { [H in keyof T]: { [_ in T[H][K] extends PropertyKey ? T[H][K] : never]: T[H][V] } }[keyof T];

type U = {
  foo: {
    id: '001'
    name: 'alan'
  }
  bar: {
    id: '002'
    name: 'dan'
  }
}

type V = CollapseKV<U, "id", "name">;
//   ^? { "001": "alan"; } | { "002": "dan"; }

TypeScript Playground

  • Related