microsoft / microsoft/TypeScript
`.then(onresolved)`'s return type should not be inferred from contextual type
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
lib Update Request
Configuration Check
My compilation target is ES2015 and my lib is the default.
Also reproducible with target ESNext, ES2022 ect.
Missing / Incorrect Definition
Promise.prototype.then
Sample Code
TypeScript infers the return type of then from the contextual type information when called with only one argument.
This can cause unexpected results
let a: string | undefined
const b = a ?? await somePromise.then(() => "str")
I expect b to be string because either a is a string, somePromise resolves and then returns a string, or somePromise rejects and await throws so b is not assigned.
However b is actually string | undefined because the contextual type on the RHS of a nullish operator is the type of the LHS
and then inferred it's return type from the context because TResult2 was not inferred from arguments.
b satisfies string | undefined
I think there's actually two issues here
- The contextual type of the RHS of nullish operator is the type of the LHS
- .then's type definition does not use overloads for different number of arguments
The first issue seems debatable, I can understand the current behavior but these alternates make sense as well
- The contextual type of R should be
unknownor the same as the wholeL ?? Rexpression - The contextual type of R should be
NonNullable<L>
Let me know if this should be a separate issue or if there is interesting reading on the current behavior.
The next issue is caused because the return type of .then is Promise<TResult1 | TResult2> and TResult2 is not inferred from then's arguments when onrejected is not provided so it's inferred from the contextual type.
I think this issue can be fixed by changing the library to use overrides
then<TResult1>(onresolved: (t: T) => TResult1): Promise<TResult1>
then<TResult1, TResult2>(onresolved: (t: T) => TResult1, onrejected: (err: any) => TResult2): Promise<TResult1 | TResult2>
// more overrides for 0 or only onrejected args.
Documentation Link
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts#L1524
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 la definición de Promise.prototype.then en src/lib/es5.d.ts alrededor de la línea 1524 y reproduce el ejemplo proporcionado del playground. Comprueba cómo están tipadas las formas de uno y dos argumentos, y determina si la cuestión de tipado contextual de nullish-operator debe tratarse por separado. Se considera terminado cuando se haya verificado el tipo previsto de la forma de un argumento sin introducir regresiones en el comportamiento documentado de Promise.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- javascript, typescript
- Área
- compilers
- Tipo de issue
- Error
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Estado de actividad
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100