Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

246
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!