Help us understand the problem. What is going on with this article?

TypeScript: 異なる2つの型システム「公称型」と「構造的部分型」

本稿では、異なる2つの型システム「公称型」と「構造的部分型」の差異について説明します。

型の互換性とは?

まず型の互換性とは何でしょうか? TypeScriptでは、ある型に別の型を代入できるかどうかが「互換性」の判断基準になります。例えば、1numberに代入できるので、1numberに互換しています。一方、truenumberに代入できないので、truenumberとは互換していないことになります。

異なる2つの型システム

TypeScriptは、互換性の有無の判断基準(つまり、代入できるかどうかの基準)が、JavaやPHPなどとは異なっています。どのように異なるのか、それぞれ見ていきましょう。

公称型 - 継承関係に着目するJava

JavaやPHPは、公称型(nominal typing)という型システムを採用しています。公称型では、型の互換性は、オブジェクト同士の継承関係(is-a関係)に着目して判断します。

例えば、AnimalUserの2つのクラスが、全く同じnameプロパティを持っていて、同じように取り扱えたとしても、お互いに継承関係が無い場合は、User型の変数にAnimalインスタンスを代入することも、その逆もできません。互換性がないわけです。逆に、CatクラスがAnimalを継承している場合、Animal型の変数にCatは代入可能です。CatAnimalとの互換性があることになります。

Astah_-__no_title_____.png

AnimalUserが同じプロパティ、同じメソッドを持っていれば、オブジェクトの「能力」は同じです。なので、Userを使うところにAnimalを使えても良さそうです。それが仕様上の間違いだとしても、論理エラーにはならないためです。

しかし、こうした交換を許さないのが公称型なのです。あくまで、継承関係があるかが大事。「能力」よりも「血統」重視の型システムと言えそうです。

構造的部分型 - 構造に着目するTypeScript

TypeScriptは、構造的部分型(structural subtyping)という型システムを採用しています。構造的部分型は、継承関係ではなく、オブジェクトが持っているプロパティが互換しているかどうか、つまり構造が同じかどうかに着目します。

例えば、AnimalUserの2つのクラスに、継承関係がなかったとしても、同じnameプロパティを持っていれば、User型の変数にAnimalを代入できます。その逆も可能です。つまり、お互いに互換性があるわけです。

Astah_-__no_title_____.png

class Animal {
  public name: string = ''
}

class User {
  public name: string = ''
}

let user: User = new User()
let animal: Animal = new Animal()
user = animal // OK
animal = user // OK

AnimalUserが同じインターフェイスならば、オブジェクトの「能力」は同じです。継承関係がなくとも、「能力」が同じかどうかが大事。「血統」よりも「能力」重視なのが構造的部分型と言えそうです。

・・・

本稿では、インターフェイスが同じならTypeScriptでは互換性があると説明しました。しかし、これは正確ではありません。同じインターフェイスを持ったクラス同士でも、互換性がない、つまり、代入できない場合があります。それについては今後の投稿で説明していきたいと思います。


最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローお願いします:relieved:Twitter@suin

suin
Qiita 4位/TypeScript入門書執筆中/TypeScripterのための座談会「YYTypeScript」主催/『実践ドメイン駆動設計』書籍邦訳レビュア/分報Slack考案/YYPHP主催/CodeIQマガジン執筆/株式会社クラフトマンソフトウェア創設/Web自動テスト「ShouldBee」の開発/TypeScript/DDD/OOP
https://yyts.connpass.com/
shouldbee
開発者向けテスト支援サービスShouldBeeを開発・運営するスタートアップ(onlab第8期)
http://shouldbee.at
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした