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

167
Vistas
is it possible to use value of some key as new key in typescript?

say i have an object list, and each object is type of IUser

type IUser = {
 id: string
 name: string
 ...
}

I want to convert this list to a map, use id as key(or other property from object).

And hope I can have an accurate typescript description for this type, so that I can use it like this const idMap :IMapKeyedByK<IUser, 'id'> = {...}

type IMapKeyedByK<T, K> = {
  [key: T[K]]: T
}

How can I implement IMapKeyedByK<T, K>?

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

0

Note that JavaScript object index types are always strings or symbols. You can index an object using numbers, but they get converted to strings: ({42: 'foo'})['42'] == 'foo'. So unless your IUser contains symbols, this is not very useful because you might as well hardcode string keys.

That said, you can do it. We have to constrain K to be a valid key type, and constrain T so that it contains a key of type K with a value that can also be used as a key.

type ObjectKey = string | number | symbol
type IMapKeyedByK<T extends Record<K, ObjectKey>, K extends ObjectKey> = Record<T[K], T>

const idMap: IMapKeyedByK<IUser, 'id'> = {}
idMap['zaphod'] = {id: 'zaphod', name: 'Zaphod Beeblebrox'} // OK
idMap[Symbol()] = {id: 'zaphod', name: 'Zaphod Beeblebrox'} // Error! Type 'symbol' cannot be used as an index type.
about 4 years ago · Juan Pablo Isaza Denunciar

0

A correct type here is:

type IMapKeyedByK<T, K extends keyof T> = T[K] extends PropertyKey // if the property value can be used as key
    ? Record<T[K], T>  // record indexed by the property value
    : never;   

It will ensure that you pass a key belonging to T and also that the value for that key is valid to use as an object key.

Example:

type IUser = {
 id: string
 name: string
 age: number
 department: {
     departmentName: string
 }
}

type IMapKeyedByK<T, K extends keyof T> = T[K] extends PropertyKey ? Record<T[K], T> : never;

type MapById   = IMapKeyedByK<IUser, "id">;   //works - indexed by string
type MapByName = IMapKeyedByK<IUser, "name">; //works - indexed by string
type MapByAge  = IMapKeyedByK<IUser, "age">;  //works - indexed by number

type MapByDepartment = IMapKeyedByK<IUser, "department">; //produces `never` because cannot be indexed by object
type MapByPhone = IMapKeyedByK<IUser, "phone">;           //error - "phone" does not exist

Playground Link

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