microsoft / microsoft/TypeScript
Contextually infer parameters for type aliases/interfaces
まだ誰も着手していません。
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.3k
- 平均マージ
- 2日 4時間
- マージ済み PR(30日)
- 132
説明
Search Terms
type alias parameter inference contextual
Suggestion
The type parameters of a type alias (or interface) should be able to be inferred when a value is being assigned/cast to that type/interface.
Use Cases/Examples
My program defines a few common types/interfaces to be used as contracts between components. E.g.
// type for an object holding a function + its inverse
type FunctionPair<T, U> = { apply(it: T): U, reverse(it: U): T };
Then, throughout the program, I need to make objects of this type. If I have a factory function (or use a class with its constructor), this isn't too bad:
function makeFunctionPair<T, U>(apply: (it: T) => U, reverse: (it: U) => T) {
return { apply, reverse } as FunctionPair<T, U>;
}
However, I'd like to be able to just write these (simple) domain objects with literals, rather than using a factory function, and then signal the type (with the implied relation between the apply and reverse properties) to the compiler with a type annotation/assertion inline:
const a: FunctionPair<string, () => string> = {
apply(it: string) { return () => it + "!!!"; },
reverse(it) { return it().slice(0, -3); }
}
However, the above is a bit verbose, in that I have to add <string, () => string> to the type annotation, whereas it seems like this should be inferrable. I'm proposing to be able to just do:
/* FunctionPair type param values inferred contextually from the assigned object */
const a: FunctionPair = {
apply(it: string) { return () => it + "!!!"; },
reverse(it) { return it().slice(0, -3); }
}
Here's another example: imagine a runtime that uses the idea of effects as data. The user sends into the runtime an object describing the effect to perform, and a callback to call with any result:
type EffectNamesWithReturnTypes = {
x: { status: 0 | 1 },
y: { changes: string[] },
};
type EffectDescriptor<T extends keyof EffectNamesWithReturnTypes> = {
name: T;
cb: (result: EffectNamesWithReturnTypes[T]) => void
}
It would be nice to be able to write:
const effect = <EffectDescriptor>{ name: "x", cb: (it) => it.status };
Rather than having to write:
const effect = <EffectDescriptor<"x">>{ name: "x", cb: (it) => it.status };
Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
この issue ではファイルもテストも指定されていません。まず、FunctionPair と EffectDescriptor の例を TypeScript のテストケースで再現し、その後、コンパイラーのコンテキスト型付けとジェネリック推論の挙動を調査してください。パラメーター化されていないエイリアスまたはインターフェースが、示されている代入形式とアサーション形式でパラメーターを推論し、既存の推論を後退させないことが完了条件です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- typescript
- 領域
- compilers
- issue の種類
- 機能追加
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100