microsoft / microsoft/TypeScript
type inference breaks with composition function using extend on generic arguments
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
Bug Report
Type inference breaks with composition function using extend on generic arguments. I came across this issue while trying to implement composition for type guard functions see. it worked mostly but in some cases was getting strange type error demonstrated here, then I tried to change type guards with functions and the issue has persisted. Meaning that it's more general issue and not specific to type guards.
🔎 Search Terms
type guard composition extend inference
🕗 Version & Regression Information
Tested on ts@4.0-4.4 and all the versions have this issue
⏯ Playground Link
Playground link with relevant code
💻 Code
type Func<Input, Output> = (value: Input) => Output;
const flow =<I, O extends I, O2 extends O>
(f: Func<I, O>,g: Func<O, O2>): Func<I, O2> =>
(i: I): O2 => g(f(i))
const pipe = <I, O>
(i: I, f: Func<I,O>): O =>
f(i)
type ABC = AB | "C"
type AB = "A" | "B"
declare const ab: AB | undefined
declare const isB: Func<ABC,"B">
declare function notUndefined<T>(input: T | undefined): T
const b: "B" = pipe(
ab,
// infered type is:
// flow<
// AB | undefined
// , AB | undefined <---- here is error `udefined` shuold be removed
// , "B">
// ( f: Func<AB | undefined, AB | undefined>
// , g: Func<AB | undefined, "B">
// ): Func<...>
flow(notUndefined, isB)
// ~~~
// because of incorectly infered type getting this error:
// Argument of type 'Func<ABC, "B">' is not assignable to parameter of type 'Func<AB | undefined, "B">'.
// Type 'AB | undefined' is not assignable to type 'ABC'.
// Type 'undefined' is not assignable to type 'ABC'.(2345)
// if I specify type arguments it will work fine:
// flow<AB | undefined,AB,"B">(notUndefined, isB)
)
// NOTE: if we were to use notUndefined without generic argument all would be just fine:
// declare function notUndefined(input: AB | undefined): AB
// NOTE: both of this work just fine
const abnn1: AB = pipe(ab, notUndefined)
const abnn2: AB = pipe(ab, flow(notUndefined,notUndefined))
// NOTE following lines compiling proves that `isB: Func<ABC,"B">` is asignable to `isB2: Func<AB, "B">`
declare const isB2: Func<AB, "B">
declare const acceptIsB2: (check: Func<AB, "B">) => void
acceptIsB2(isB)
acceptIsB2(isB2)
🙁 Actual behavior
as shown in code snippet type is inferred incorrectly and I'm getting compiler error .
🙂 Expected behavior
type should be inferred correctly.
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
Empieza ejecutando la reproducción vinculada en TypeScript Playground y compara flow(notUndefined, isB) con los argumentos de tipo proporcionados explícitamente. Rastrea cómo se infieren los argumentos genéricos para la función de composición. Se considera terminado cuando el ejemplo infiere el tipo intermedio sin incluir undefined y compila con el resultado esperado "B".
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
- 45/100