microsoft / microsoft/TypeScript

Allow classes to implement unions of object types

オープン
#62,630 コメント 17 件 リアクション 4 件 担当者 0 名 GitHub で見る

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

Awaiting More Feedback Suggestion
主要言語
Go
スター
111k
フォーク
14.3k
平均マージ
2日 4時間
マージ済み PR(30日)
132

説明

🔍 Search Terms

class extends union type

✅ Viability Checklist
⭐ Suggestion

Allow classes to extend unions of object types when the types in the union have the same set of properties.

The goal is to allow type-narrowing on class instances by checking a discriminant field.

📃 Motivating Example

I often have classes that represent data that can be in one of several states, and whose fields depend on that state.

An example is an object that is imported into a database with a long task. The app will write a record to the database to indication that it's currently being imported, and locking it from other writers.

We might model that with two interfaces: ImportingFoo, and ImportedFoo, discriminated by a status field:

type FooStates = ImportingFoo | ImportedFoo;

interface ImportingFoo {
  status: 'importing';
  value: undefined;
}

interface ImportedFoo  {
  status: 'imported';
  value: string;
}

We want our class to implement this type to indicate what type value can be depending on the type of status:

class Foo implements FooStates {
  status: 'importing' | 'imported' = 'importing';
  value: undefined | string;
}

This currently gives a "A class can only implement an object type or intersection of object types with statically known members.(2422)" error.

If we could do that, we could use narrowing for the instance:

const getValue = (foo: Foo): string => {
  if (foo.status === 'imported') {
    return foo.value; // OK, because foo narrowed to a ImportedFoo
  }
  throw new Error('Invalid state');
}
💻 Use Cases
  1. What do you want to use this for?
  • Classes that act as discriminated unions
  1. What shortcomings exist with current approaches?
  • The class can't explicitly implement the union, narrowing doesn't automatically work
  1. What workarounds are you using in the meantime?
  • Cast the instance to an intersection of the class and interface: foo as Foo & ImportedFoo, but this is error prone as the cast will succeed in cases where it shouldn't.

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

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

はじめの一歩

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

調査の方向性

まず、診断 2422 を生成するクラスの implements 検証を追跡し、次にクラスインスタンスに対する判別共用体の narrowing がどのように機能するかを調べます。提案されている FooStatesFoo の例を比較し、クラスの実装と narrowing を対象とするコンパイラテストを特定します。完了条件は、有効な共用体の実装が受け入れられ、示されている foo.status のチェックによって foo.value が正しく絞り込まれ、JavaScript 出力が変更されないことです。

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

評価

技術スタック
typescript
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

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

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