microsoft / microsoft/TypeScript
type inference breaks with composition function using extend on generic arguments
Personne n'a encore pris cette issue.
- Langage dominant
- Go
- Étoiles
- 111k
- Forks
- 14.4k
- Merge moyen
- 1 j 19 h
- PR mergées (30 j)
- 117
Description
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.
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Piste de recherche
Commencez par exécuter la reproduction liée dans TypeScript Playground et comparez flow(notUndefined, isB) avec les arguments de type fournis explicitement. Suivez la manière dont les arguments génériques sont inférés pour la fonction de composition. C'est terminé lorsque l'exemple infère le type intermédiaire sans inclure undefined et se compile avec le résultat attendu "B".
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- typescript
- Domaine
- compilers
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100