microsoft / microsoft/TypeScript

Object properties are inferred in the wrong order: should infer properties with `NoInfer<T>` AFTER properties with `T`

オープン
#63,378 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Domain: check: Type Inference Possible Improvement
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

🔎 Search Terms

NoInfer
brittle inference
object properties

Related issues:

🕗 Version & Regression Information

Tested in 6.0.2 and nightly.

⏯ Playground Link

Playground Link

💻 Code

See playground for the full example.

type fooArgs<T> = {
     a: (_: A) => X<T>,
     // note: NoInfer<Y<T>> better than Y<NoInfer<T>>, doesn't change this issue though
     b: NoInfer<Y<T>>
}

function foo<T>(args: fooArgs<T>) {}

foo({
     a: (_) => ...,
     b: ... // inference of the value given to b is VERY brittle.
});
🙁 Actual behavior

Sometimes, b is inferred before a.

Then, as a is the one used to infer the generic parameter T, the value given to b doesn't have the correct type (because inferred before a).
This is likely due to the fact that the value given to a is a callback with a parameter we didn't specify the type ((_) => ...). Therefore, TS has first to look at fooArgs<T> to infer the callback's parameter type (i.e. the type of _).

Due to that, b is sometime inferred before a has been properly inferred. This behavior depends on the order of the object properties (cf related issue). It is also influenced by other defined properties, and how they are defined. Making the inference quite chaotic.

🙂 Expected behavior

TS should infer NoInfer<T> properties AFTER T properties, in order to prevent such issues.

Additional information about the issue

The fact that the order of the inference changes is quite troublesome, hiding the issue in some cases.

Could be nice to have a kind of tool/flag to detect such kind of potential issues, and to help debugging.

EDIT: A possible workaround:

type fooArgs<T> = {
     b: Y<T>
}

function foo<T>(a: (_: A) => X<T>, args: NoInfer<fooArgs<T>>) {}

foo(
     a: (_) => ..., {
         b: ...
     });

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされている Playground と、縮小した fooArgs/foo の例から始め、オブジェクトプロパティの順序とコールバックパラメーターの注釈を変えてください。NoInfer プロパティがどのように推論されるかを追跡しながら、関連する issue #56297 と動作を比較してください。完了の条件は、例が NoInfer プロパティより前に T を含むプロパティから一貫して T を推論し、報告されている順序依存の動作が解消されていることです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
typescript
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
42/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。