microsoft / microsoft/TypeScript

type inference breaks with composition function using extend on generic arguments

Abierto
#44,384 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Needs Investigation
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

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. 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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.