ume

Typescript 構造的型付け

前書き

Typescriptでは以下のPersonクラスのwalkメソッドとDogクラスのwalkメソッドは互換性がある(同じ)メソッドとして認識されるのかされないのか。上記がピンとこないは読み進めていただけると幸いです。

class Person {
  walk() {}
}
 
class Dog {
  walk() {}
}

結論

Typescriptでは↑(PersonクラスのwalkメソッドとDogクラスのwalkメソッド)は互換性(同じメソッド)があるとして認識されます。(構造的型付け)

名前的型付けと構造的型付け

名前的型付けと構造的型付けという概念がある。 これは2つの別々のクラス(PersonとDog)で同名のメソッド(walk)が定義されていたときに, PersonクラスのwalkメソッドとDogクラスのwalkメソッドを同じと判定するか別物と判定するかの違い

名前的型付け

⇨クラス名が別だと同名のメソッドがあっても互換性ないメソッドとして認識される。 なので↓の2つのwalkメソッドは同じものとして認識される。 名前的型付け:Java, C#, Swift, PHP

class Person {
  walk() {} 
}
 
class Dog {
  walk() {}
}

構造的型付け

⇨メソッドの構造が同じなら互換性(同じ)のあるメソッドとして認識される。 構造が同じとは?
⇨メソッドの引数の有無が同じ、戻り値の有無が同じ.
なのでクラス名が異なってるが同じメソッドとして認識される。
構造的型付け:TypeScript, Go

class Person {
  walk() {} 
}
 
class Dog {
  walk() {}
}

構造的型付けの利点

// 同じメソッドとして扱うこと(構造的型付け)の利点⇨型(walkable)を異なるクラスの同名のメソッドの型指定に使いまわせる

interface Walkable {
  walk(): void;
}

class Person {
  walk() {
    console.log("人が歩いています");
  }
}

class Dog {
  walk() {
    console.log("犬が歩いています");
  }
}

function takeAWalk(walker: Walkable) {
  walker.walk();
}

const person = new Person();
const dog = new Dog();

takeAWalk(person); // 出力: 人が歩いています
takeAWalk(dog);    // 出力: 犬が歩いています
// person,dog,両方のインスタンスのwalkメソッドの型をWalkableで型を調べれる

参考情報

typescriptbook.jp

まとめ

  • プログラミング言語には名前的型付けと構造的型付けという2つの概念がある。

  • typescriptは構造的型付け