Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

295
Vistas
how to convert Record to another Record with different keys in typescript

I have a function convert, its parameter is an object, the value can be function or an object contains three properties, the type looks like this.

type Input = {
  [K: string]: () => any | { pending: () => any, fulfilled: () => any, rejected: {} => any }
}

I hope can return an object, that the keys will generate by the values, for example:

const result = convert({
  sync() {},
  async: {
    pending() {},
    fulfilled() {},
    rejected() {}
  }
});
// the keys of result
result.sync();
result.asyncPending();
result.asyncFulfilled();
result.asyncRejected();

currently, I know how to generate result by the keys and the string literals

type Result<Input> = {
  [key in keyof Input as `${string & key}Fulfilled`]: any
}

but can't meet my requirement, I google for a long time, but can't found the solution.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

My proposed solution would look like this:

type Input = {
  [key: string]: { pending: () => any, fulfilled: () => any, rejected: () => any } | (() => any)
}

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type Result<Input> = {
  [K in keyof Input as Input[K] extends () => any ? K : never]: Input[K]
} & UnionToIntersection<{
  [K in keyof Input]: { 
    [K2 in keyof Input[K] as `${K & string}${Capitalize<K2 & string>}`]: Input[K][K2] 
  }
}[keyof Input]> extends infer O ? { [K in keyof O]: O[K] } : never

function convert<T extends Input>(arg: T): Result<T> {
    return {} as any
}

For each property K of Input where the type is an object we map over the keys in Input[K]. For each key K2 inside Input[K], we rename the key to ${K & string}${Capitalize<K2 & string>} and return the type Input[K][K2]. The resulting mapped object is converted to a union by indexing it with keyof Input.

This union can be converted to an intersection with UnionToIntersection to get all nested keys a level higher.

Now result has the correct type:


const result = convert({
  sync() {},
  async: {
      pending() {},
      fulfilled() {},
      rejected() {}
  }
});
// const result: {
//     sync: () => void;
//     asyncPending: () => void;
//     asyncFulfilled: () => void;
//     asyncRejected: () => void;
// }

result.sync();
result.asyncPending();
result.asyncFulfilled();
result.asyncRejected();

Playground

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda