Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

171
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda