microsoft / microsoft/TypeScript
type inference breaks with composition function using extend on generic arguments
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
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.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo la riproduzione collegata in TypeScript Playground e confrontando flow(notUndefined, isB) con gli argomenti di tipo forniti esplicitamente. Traccia il modo in cui vengono inferiti gli argomenti generici per la funzione di composizione. Il lavoro è completo quando l'esempio inferisce il tipo intermedio senza includere undefined e compila con il risultato atteso "B".
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100