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

132
Visualizações
How to reduce an array to object while providing auto code completion in typescript?

Lately I'm trying out typescript and while diving into it I was stuck at one place where I wasn't able move forward. So I have an array of strings and I want to reduce it into an object while getting all proper hinting and code completion. Although I've arrived to a place where typescript isn't throwing any error but still I wasn't able to achieve the code completion behaviour. Pasting out the sample code here for reference.

interface GetObjI {
  [key: string]: string;
}

function getObj(myArray: string[]): GetObjI {
  return myArray.reduce((prev, curr) => {
    prev[curr] = curr;
    return prev;
  }, {});
}

const arr = ["name", "age"];

const obj = getObj(arr);

console.log(obj.age); // Here I wasn't able to achieve code completion.
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

With strict TypeScript settings, the code you have should be throwing an error.

prev[curr] = curr;

throws

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.

No index signature with a parameter of type 'string' was found on type '{}'.(7053)

Which makes sense - you aren't providing any special type for the accumulator when you're passing it in, so assigning to a property of it doesn't mesh with its existing type (as an empty object).

Use a generic type argument to indicate the type of the accumulator, and make getObj generic too so that the values in myArray can be passed along (rather than using just string[], which is too general).

You also need to type the array passed in as const so it doesn't get widened to string[] before the function call.

function getObj<T extends readonly string[]>(myArray: T) {
    // Type out the type of the full object with all properties here to be DRY
    type Accum = Record<T[number], T[number]>;
    // The object doesn't have all properties inside the callback, though
    // so we need to use Partial to indicate that some or all can be missing
    return myArray.reduce<Partial<Accum>>((prev, curr: T[number]) => {
        prev[curr] = curr;
        return prev;
    }, {}) as Accum; // When returning, indicate that it's no longer Partial, but has all properties
}

const arr = ["name", "age"] as const;

const obj = getObj(arr);

console.log(obj.age);

But .reduce is not the right tool for this situation - it requires verbose TypeScript typing and is not a great idea even in standard JavaScript because the accumulator remains the same object. Just use a loop.

function getObj<T extends readonly string[]>(myArray: T) {
    const obj: Record<string, string> = {};
    for (const prop of myArray) {
        obj[prop] = prop;
    }
    return obj as Record<T[number], T[number]>;
}

Or use Object.fromEntries

const getObj = <T extends readonly string[]>(myArray: T) =>
    Object.fromEntries(myArray.map(prop => [prop, prop])) as Record<T[number], T[number]>;

Unfortunately, all of these approaches do require helping TS along with some type assertions. Using a loop or reduce requires the properties to be typed as optional inside the loop, but required outside of it - and Object.fromEntries only gives a type of Record<string, T> in response, which isn't quite specific enough.

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