microsoft / microsoft/TypeScript

Infer array as tuple when used as rest argument in a complex expression

Offen
#56,765 3 Kommentare 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Domain: check: Type Inference Help Wanted Possible Improvement
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

🔍 Search Terms

"infer rest array type"
"infer rest array args"
"infer rest array tuple"
"spread argument array expression "

✅ Viability Checklist
⭐ Suggestion

Given the following function

function foo (a: number, b: string, c: boolean) {}

TypeScript already supports inferring that an array used as rest argument should be considered as a tuple:

foo (1, ...(["a", true])) // Works

But if you add some condition to the mix, type inference breaks:

const someCondition = true

foo (1, ...(someCondition ? ["a", true] : ['b', false])) // A spread argument must either have a tuple type or be passed to a rest parameter.(2556)

My suggestion it to add support for inlined array inside complex expression to be used as spread args.

Playground link

📃 Motivating Example

I came accros this issue while designing a database agnostic module based on kysely.

I used to write stuff like so:


const myTableWithId =
  dialect === 'pg'
    ? db.schema
        .createTable('my_table')
        .addColumn('id', 'bigserial', (col) => col.primaryKey())
    : db.schema
        .createTable('my_table')
        .addColumn('id', 'bigint', (col) => col.autoIncrement().primaryKey())

await myTableWithId
  .addColumn('my_col', 'varchar', (col) => col.notNullable())
  .execute()

But this breaks the linear style of the definition. The following notation is more natural:

await db.schema
  .createTable('oauth_device')
  .addColumn(
    'id',
    ...(dialect === 'pg'
      ? ['bigserial', (col) => col.primaryKey()]
      : ['bigint', (col) => col.autoIncrement().primaryKey()])
  )
  .addColumn('my_col', 'varchar', (col) => col.notNullable())
  .execute()

It currently work but requires additional typecasting (see playground link before)

💻 Use Cases
  1. What do you want to use this for? Be able to write more readable code
  2. What shortcomings exist with current approaches? Unnecessarily more verbose
  3. What workarounds are you using in the meantime? Declare the type of the spread tuple and cast every value to that type

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie mit den verlinkten TypeScript Playground-Beispielen und vergleichen Sie den direkten tuple spread mit dem conditional spread im issue. Die Arbeit ist abgeschlossen, wenn ein inline conditional array expression als spread arguments für die gezeigten typisierten Funktionen ohne type assertions verwendet werden kann, während das Laufzeitverhalten von JavaScript unverändert bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.