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

136
Visualizações
Typescript Pick optionnal unset variable

I'm trying to use the "pick" function of typescript to get all the possible values of my objects. My objects have optional attributes so they are not necessarily set

const foo = [
    {
      name: 'index',
    },
    {
      name: 'id',
      type: 'number',
    },
    {
      name: 'error',
    },
  ] as const

type ElementArg<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType>
  ? Pick<ElementType, 'name' | 'type'>
  : never

type result = ElementArg<typeof foo>
//result : {name: "index" | "id" | "error"}
//expected : {name: "index" | "id" | "error" type: "number" | "undefined"}

and I also try to convert "type" attribut to a type with :

type typeDecoder<T> = T extends 'number' ? number
  : T extends 'number[]' ? number[]
    : T extends 'string' ? string
      : T extends 'string[]' ? string[]
        : T extends 'boolean' ? boolean
          : T extends 'undefined' ? undefined
            : never;

but I think there is a better way to do it and I don't know where to use my function

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

I managed to get something to work:

type ElementArg<T extends ReadonlyArray<unknown>, R extends {} = {}> = T extends readonly [infer First, ...infer Rest]
  ? ElementArg<Rest, {
    [K in keyof First | keyof R]:
      K extends keyof R
        ? K extends keyof First
          ? R[K] | First[K]
          : R[K] | "undefined"
        : K extends keyof First
          ? First[K]
          : never
  }>
  : R;

The main idea is that we loop through each of the elements in the tuple and then we add to the result we accumulate.

T extends readonly [infer First, ...infer Rest]

Here we get the first element and the rest as a tuple. Next is this big chunk:

  ElementArg<Rest, {
    [K in keyof First | keyof R]:
      K extends keyof R
        ? K extends keyof First
          ? R[K] | First[K]
          : R[K] | "undefined"
        : K extends keyof First
          ? First[K]
          : never
  }>

We use ElementArg again on the remaining elements, and then the long complicated mapped type correctly adds this element's contents to the results.

The logic is like this:

  • For each key in the element or result

  • If the key is a key of the result

    • If the key is a key of the element

      • Add the key's value to the result
    • Otherwise

      • Add "undefined" to the result
  • Or else if the key is a key of the element

    • This is a new key we add to the result

And finally if the first step where we attempt to get the first element does not work, that means T is empty and we are done, so we return R.

Playground

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