microsoft / microsoft/TypeScript
Resolve deferred conditional types to their `true` branch when instantiated with a type parameter constrained to the tested type
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.4k
- 平均マージ
- 1日 19時間
- マージ済み PR(30日)
- 117
説明
Bug Report
🔎 Search Terms
conditional-type, distributive-type, generics
🕗 Version & Regression Information
Version 4.9.4 and nightly
⏯ Playground Link
TS resolves type to different type even if I add constraint that should resolve to given type
💻 Code
type PrimitiveDataType = string | number | bigint | boolean | symbol | undefined | null;
type ConditionalType<T> = [T] extends [PrimitiveDataType]
? (v: T) => void
: T extends Array<unknown>
? (v: T, t: number) => void
: never;
abstract class AbstractClass<T> {
abstract value: T;
protected conditionalFunctions: Map<ConditionalType<T>, number | undefined> = new Map();
}
class SomeClass<T extends PrimitiveDataType> extends AbstractClass<T> {
value: T;
constructor(value: T) {
super();
this.value = value;
}
someMethod() {
for (const someFn of this.conditionalFunctions.keys()) {
someFn(this.value);
}
}
}
In the above code I have created a PrimitiveDataType which is a union of all primitive data types in JavaScript. Then I have created a ConditionalType<T> that will resolve to some callback only if T is one of PrimitiveDataType. Then I have created an abstract generic class that have a field which type(ConditionalType<T>) depends on generic value of this class. In the end, I have crated a SomeClass that extends AbstractClass<T> and add constraints that generic parameter T have to extend PrimitiveDataType.
🙁 Actual behavior
For someMethod of this SomeClass conditionalFunctions.keys() is resolved to (v: T, t: number) => void what would implicate that my generic T extends an Array type.
🙂 Expected behavior
For someMethod of this SomeClass I have expected that TS should resolve conditionalFunctions.keys() to (v: T) => void to my surprise it is resolved to (v: T, t: number) => void what would implicate that my generic T extends an Array type. This doesn't make sens to me because T has constraint that has to extends PrimitiveDataType.
Example of what I would expect:
type PrimitiveDataType = string | number | bigint | boolean | symbol | undefined | null;
type ConditionalType<T> = [T] extends [PrimitiveDataType]
? (v: T) => void
: T extends Array<unknown>
? (v: T, t: number) => void
: never;
const x: PrimitiveDataType = 12;
const y: ConditionalType<typeof x> = (param: number) => undefined;
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
リンクされている TypeScript Playground の再現例から始め、ジェネリックな SomeClass のケースと通常の変数の例を比較してください。PrimitiveDataType に制約された型パラメーターに対する条件型のインスタンス化を調査してください。制約されたケースで ConditionalType が配列分岐ではなく 1 引数のコールバックに解決され、両方の例が一貫して動作すれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100