Skip to content

fix(types): EscapableArray allows supported primitive types #1072

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ParisDuvalA
Copy link

Purely a TypeScript change. This TypeScript-compiles when part of other projects and I assume that the tests work on it as expected but am not able to execute the unit tests in my environment.

The example in the Multiple updates in one query section of the read-me presently reads:

const users = [
  [1, 'John', 34],
  [2, 'Jane', 27],
]

sql`
  update users set name = update_data.name, age = update_data.age
  from (values ${sql(users)}) as update_data (id, name, age)
  where users.id = update_data.id
`

Following this, you would expect the below to TypeScript-compile,

import postgres from "postgres";

const sql = postgres({
    host: `${process.env.DB_HOSTNAME}`,
    port: Number(process.env.DB_PORT),
    database: `${process.env.DB_NAME}`,
    username: `${process.env.DB_USERNAME}`,
    password: `${process.env.DB_PASSWORD}`,
    transform: {
        undefined: null, // unsure if this is relevant to the issue but it is used in my use case
    },
});

interface Customer { first_name: string; last_name: string; age: number; mobile: string }

async function createCustomers(customers: Customer[]) {      
    await sql`INSERT INTO customers FROM (VALUES ${sql(customers.map(x => ([x.first_name, x.last_name, x.age, x.mobile] as const)))});`;
}

and it does.

type EscapableArray = (string | number)[];

is set in the types/index.d.ts and used in the First type temploid for sql(input) uses where the input is a primitive array of arrays as above. However, for nested data that isn't just string/number, this does not TypeScript-compile but this is supported by the query-builder itself.

For example, changing the Customer interface to

interface Customer { first_name: string; last_name: string; age: number; mobile: string | null }

the project no longer TypeScript-compiles but if you just transpile ignoring type errors (or make frequent use of as any) and then run createCustomers([{first_name:"Paris",last_name:"Duval",age:25,mobile:null}]), it inserts the data just fine (I did not directly test this, it works for my use case and I am almost certain that it would work for this minimal example as it does for the similar example below), the null is value accepted just fine.

Similarly,

console.log( sql`SELECT * FROM (VALUES ${sql([[1,'john',null],[2,'john',true],[3,'john',null],['4',null,'asdf']] as any)})`.execute().then(x=>console.log(x)));

works just fine, printing:

Result(4) [
  { column1: '1', column2: 'john', column3: null },
  { column1: '2', column2: 'john', column3: true },
  { column1: '3', column2: 'john', column3: null },
  { column1: '4', column2: null, column3: false }
]

This leads me to believe that this problem is just a discrepancy between the types supported in the TypeScript declarations file and in the JavaScript source. In case this comes up, using sql.array does not help here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant