I have the following Typescript function that query a table in Postgresql;I pass a generic type and I expect to have an array of objects of the same type passed as input, but it doesn't:
export async function pgQuery<T>(
query: string,
postgreSqlClient: Client = postgreSqlClientGlobal
) {
const log = extendLogger(_log, pgQuery);
try {
const res = await postgreSqlClient.query<T>(query);
return res;
} catch (error) {
log.error({ error }, `PostgreSql query ERROR`);
throw new Error(`PostgreSql query ERROR - ${error}`);
}
}
The input type T is:
{country: string,
age_min: number,
age_max: number}
And in the table of the Postgresql DB I have records like this:
{
loc_name: "Albania",
age_min: 15,
age_max: 64
}
but I have, as output of the executed query, object like this:
{country: string,
age_min: string,
age_max: string}
Example:
{
loc_name: "Albania",
age_min: "15",
age_max: "64"
}
How to retrieve the correct types?
pg stands for: https://github.com/brianc/node-postgres
CodePudding user response:
It depends on how postgreSqlClient.query<T>(query)
is implemented.
When you interact with an external database, just typing the request as type T
is not enough to guarantee that you will actually get a value of type T
.
When you declare the type as T
, Typescript will just trust you and assume that the type is T
. However, since you are fetching an external resource, you cannot be sure at runtime that the value is actually of type T
.
If you want to be 100% sure, you must implement some sort of runtime validation. Libraries like zod and io-ts are made for this purpose.
CodePudding user response:
The fastest solution (I'm writing a "disposable code"...) is to cast the fields in the postgresql query (es.: select loc_name, age_min::int, age_max::int from table;); for more info see:
pg-promise returns integers as strings