Suggestion: Allow interfaces to "implement" (vs extend) other interfaces

オープン
#24,274 コメント 29 件 リアクション 60 件 担当者 0 名 GitHub で見る

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

評価

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

調査の方向性

issue ではファイルもテストも指定されていません。まず、コンパイラが interface extends 宣言をどのように処理しているかを追跡し、合意された設計について議論を確認します。その後、メンバー継承なしで適合性を定義します。例をカバーするコンパイラテストを追加し、新しい構文が必須メンバーをチェックしつつ、出力される JavaScript を変更しないことを検証します。

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

説明

Awaiting More Feedback Suggestion

Search Terms

interface, implements

Suggestion

Allow declaring that an interface "implements" another interface or interfaces, which means the compiler checks conformance, but unlike the "extends" clause, no members are inherited:

interface Foo {
  foo(): void;
}

interface Bar implements Foo {
  foo(): void; // must be present to satisfy type-checker
  bar(): void;
}

Use Cases

It is very common for one interface to be an "extension" of another, but the "extends" keyword is not a universal way to make this fact explicit in code. Because of structural typing, the fact that one interface is assignable to another is true with or without "extends," so you might say the "extends" keyword serves primarily to inherit members, and secondarily to document and enforce the relationship between the two types. Inheriting members comes with a readability trade-off and is not always desirable, so it would be useful to be able to document and enforce the relationship between two interfaces without inheriting members.

Consider code such as:

import { GestureHandler } from './GestureHandler'
import { DropTarget } from './DropTarget'

export interface DragAndDropHandler extends GestureHandler {
  updateDropTarget(dropTarget: DropTaget): void;
}

function createDragAndDropHandler(/*...*/): DragAndDropHandler {
  //...
}

While this code is not bad, it is notable that DragAndDropHandler omits some of its members simply because it has a relationship with GestureHandler. What are those members? What if I would like to declare them explicitly, just as I would if GestureHandler didn't exist, or if DragAndDropHandler were a class that implemented GestureHandler? I could write them in, but the compiler won't check that I have included all of them. I could omit extends GestureHandler, but then the type-checking will happen where DragAndDropHandler is used as a GestureHandler, not where it is defined.

What I really want to do is be explicit about — and have the compiler check — that I am specifying all members of this interface, and also that it conforms to GestureHandler.

I would like to be able to write:

export interface DragAndDropHandler implements GestureHandler {
  updateDropTarget(dropTarget: DropTaget): void;
  move(gestureInfo: GestureInfo): void
  finish(gestureInfo: GestureInfo, success: boolean): void
}

Examples

See above

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. new expression-level syntax)
主要言語
Go
スター
111k
フォーク
14.4k
平均マージ
1日 19時間
マージ済み PR(30日)
117

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

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

はじめの一歩

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

microsoft/TypeScript のほかの issue

microsoft/TypeScript の issue をすべて見る

似ている issue

Go の issue をもっと見る

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

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