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

252
Visualizações
Typescript returning array of objects with unknown keys

I'm new to TypeScript, and trying to slowly migrate an existing JS (react) project to TypeScript.

I have a function executing a query:

/**
 * Run a Query against the currently connected database
 * @param {String} sql Query to run
 * @param {Object[]} Array of objects to be used in the prepared statement
 * @returns {Promise<Object[]>} Promise resolving after query is done. Returns an array of arrays with the result.
 */
const query = (sql, params) => {
  //Database stuff
}

And I'm calling this in numerous locations:

  const result = await query('SELECT count(*) as cnt from Table id=?',[2]')
  return result[0].cnt

The last line gives an error, because the field 'cnt' is unknown. How to best solve this? The return type is always Object[], but the content ob the object depends on the query.

Any suggestions how to best move this code to TS?

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

0

This is one of those places where the type system has to just be told what you're expecting. Naturally, you have to take great care when doing that to ensure you're giving the type system accurate information. Typically you want to do this as early as possible so that the more complex code built on it can rely on the types.

So an answer in two parts:

  1. How to type query, and

  2. A suggestion for avoiding using query directly

First, you can make query a generic function by giving it a generic type parameter to tell it what kinds of objects it returns:

/**
 * Run a Query against the currently connected database
 * @param {string} sql Query to run
 * @param {any[]} Array of objects to be used in the prepared statement
 * @returns {Promise<ResultType[]>} Promise resolving after query is done. Returns an array of arrays with the result.
 */
const query = <ResultType extends object>(sql: string, params: any[]): Promise<ResultType[]> => {
// −−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^^
    //Database stuff
};

Then for example you could use it like this:

const result = await query<{cnt: number}>('SELECT count(*) as cnt from Table id=?', [2]);
// −−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^
return result[0].cnt;

But here's where #2 comes in: I wouldn't do that except in a function you define once whose job is to tell you how many rows match:

async function getCountFromExampleTable(id: number): Promise<number> {
    const result = await query<{cnt: number}>('SELECT count(*) as cnt from Table id=?', [id]);
    return result[0].cnt;
}

It's really easy to look at getCountFromExampleTable and know that the type argument we're giving ({cnt: number}) is correct. Then any code that needs to do this can reuse getCountFromExampleTable rather than having to provide that type argument (and possibly get it wrong).

You'd probably want getCountFromExampleTable to be more generic, perhaps accepting the table name and the parameters, but you get the idea. (If so, be sure to test the table name to ensure it can't be used as part of an SQL injection attack, and continue to use a prepared statement as you already are.)

Playground link

about 4 years ago · Juan Pablo Isaza Relatório

0

You have to use generics

const query = <T>(sql: string, params: Object[]): T[] => {
    return []
}

But function can return empty array. In this case you can check cnt property like this

const result = await query('SELECT count(*) as cnt from Table id=?',[2])
return result[0]?.cnt
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