microsoft / microsoft/TypeScript
Infer array as tuple when used as rest argument in a complex expression
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.4k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Descripción
🔍 Search Terms
"infer rest array type"
"infer rest array args"
"infer rest array tuple"
"spread argument array expression "
✅ Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ 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.
📃 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
- What do you want to use this for? Be able to write more readable code
- What shortcomings exist with current approaches? Unnecessarily more verbose
- What workarounds are you using in the meantime? Declare the type of the spread tuple and cast every value to that type
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza con los ejemplos enlazados de TypeScript Playground y compara el tuple spread directo con el conditional spread del issue. El trabajo estará terminado cuando una inline conditional array expression pueda usarse como spread arguments para las funciones tipadas mostradas sin type assertions, mientras el comportamiento de JavaScript en tiempo de ejecución permanezca sin cambios.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- typescript
- Área
- compilers
- Tipo de issue
- Nueva funcionalidad
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100