microsoft / microsoft/TypeScript
type inference breaks with composition function using extend on generic arguments
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.4k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 117
説明
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.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、リンクされた TypeScript Playground の再現例を実行し、flow(notUndefined, isB) と明示的に指定された型引数を比較します。合成関数に対してジェネリック引数がどのように推論されるかを追跡します。サンプルが undefined を含めずに中間型を推論し、期待される "B" の結果でコンパイルできれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 45/100