microsoft / microsoft/TypeScript
Rest parameter in callback function using generic tuple types: Forces definition of all parameters
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.3k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Descripción
TypeScript Version: 3.8.0-dev.20191116
Search Terms:
rest parameter, spread, tuple type, generics, conditional types
Code
https://github.com/BTOdell/typescript-tuple-rest-spread-bug
This issue was discovered when implementing a type-safe event emitter class. I've produced a minimum reproducible example at the GitHub link above as well as in a Playground link below.
index.tsdefines an unimplementedEventEmitterthat includes 4 functions which should be equivalent (except for theeventNameparameter).test.tsconsumes theEventEmitterclass and calls the various functions to test type-safety.
An Events interface is used to define the supported events by mapping the event name to a tuple type for the parameters of the event listener.
This interface is passed through a generic parameter E in the Test class and then passed through a generic parameter E in the EventEmitter class.
Expected behavior:
A listener function should be able to define 1 parameter even if the caller might pass 2 parameters. The listener will then only have access to the first parameter passed. This is how JavaScript normally behaves.
Actual behavior:
The unexpected behavior occurs on lines 29 and 33 (in test.ts) and only occurs when the Events interface type has to pass through 2 generic class parameters.
If line 14 is uncommented, and line 13 is commented then all unexpected behavior is resolved.
Error:(29, 47) TS2345: Argument of type '(b: boolean) => void' is not assignable to parameter of type '(...args: Args<E["multiArray"]>) => any'.
Types of parameters 'b' and 'args' are incompatible.
Type 'Args<E["multiArray"]>' is not assignable to type '[boolean]'.
Type 'E["multiArray"] | [E["multiArray"]]' is not assignable to type '[boolean]'.
Type 'any[] & E["multiArray"]' is not assignable to type '[boolean]'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
Type '[boolean, boolean]' is not assignable to type '[boolean]'.
Types of property 'length' are incompatible.
Type '2' is not assignable to type '1'.
It seems like the tuple types [boolean, boolean] and [boolean] are not being treated like they're being spread as a rest parameter in a function. Could the context information be getting lost due to jumping through multiple generic parameters?
Playground Link:
Playground link
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 reproduciendo los errores de las líneas 29 y 33 de test.ts en el ejemplo mínimo reproducible enlazado y, después, inspecciona las definiciones relacionadas en index.ts. Confirma el comportamiento esperado comprobando que se acepta un listener de un parámetro para una tupla de dos parámetros, mientras se mantiene la seguridad de tipos.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- typescript
- Área
- compilers
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100