LoginSignup
1
1

TypeScriptって「構造的部分型」なんだ。っていう話

Last updated at Posted at 2024-05-28

実装していて 「構造的部分型」 なんて意識していなかったけど、「構造的部分型」をちょっと理解していると、下記のサンプルがなんで実装エラー(静的型チェックエラー)にならず、実行できるのか理解できるよ、っていう話。

class Person {
  public talk() {
    console.log('こんちは');
  }
}
 
class Dog {
  public talk() {
    console.log('ワン!');
  }
}

const person = new Person();

const dog: Dog = person; // ←これエラーにならないよ!!

dog.talk();

実行結果

こんにちは

PersonクラスってDogクラスから派生してるわけでもなく、なんでエラーにならないんだ?? :thinking:
Javaなら間違いなくエラーになりますよね。

このエラーにならない理由が、TypeScriptが「構造的部分型(構造的型付け)」型システムを採用しているからです。

構造的部分型は、型の「名前」や「継承関係」ではなく、オブジェクトが持っている「プロパティ」が互換しているかどうか、つまり構造が一致しているかどうかで判断します。

先ほどの例では、PersonもDocもtalkメソッドを持っているので、構造的に一致している為エラーになりませんでした。
image.png

なので、こちらはエラーになります。

class Person {
  public talk() {
    console.log('こんちは');
  }
}
 
class Dog {
  public bark() {
    console.log('ワン!');
  }
}

const person = new Person();
// エラー: Property 'bark' is missing in type 'Person' but required in type 'Dog'.ts(2741)
const dog: Dog = person; 

image.png

構造的部分型について詳細を理解したい方は、こちらをどうぞ。

ところで、Javaは「公称型(名前的型付け)」型システムを採用し、型の「名前」、「継承関係」で型が互換しているかどうか判断します。

公称型については、こちらをどうぞ。

TypeScriptもクラスを公称型クラスにすることは可能です。
公称型クラスにすることによって、構造が同じでも型不一致になります。

公称型クラスにするには、非publicなプロパティが1つでもあると公称型クラスになります。

以下のサンプルは、公称型クラスなので、PersonクラスのインスタンスをDogクラスの変数に代入すると実装エラーになります。

class Person {
  private _name: string;

  public constructor(name: string) {
    this._name = name;
  }

  public talk() {
    console.log('こんちは');
  }
}
 
class Dog {
  private _name: string;

  public constructor(name: string) {
    this._name = name;
  }

  public talk() {
    console.log('ワン!');
  }
}

const person = new Person('あおき');
// エラー: Type 'Person' is not assignable to type 'Dog'.  Types have separate declarations of a private property '_name'.ts(2322) 
const dog: Dog = person; 

interfaceで公称型にすることができるそうなのですが、TypeScriptの仕様ではなく、テクニックで実現できるようです。
興味がある方は、こちらをどうぞ。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1