🎉

【TS】型エイリアス(type)とインターフェイスの違いとは!!!

2022/04/10に公開約2,200字

これは何?

今、フロントの開発力をつけるためにオライリーの「プログラミング Typescript」を読み進めながらTypescriptを勉強しております。
その際に、Typescriptの中で出てくる型エイリアス(type)とインターフェイスの違いが勉強になったため備忘録としてまとめました!

そもそも、型エイリアス(type)とインターフェイスって何?

型エイリアス(type)は、型に対して名前をつけることができます。
以下のように typeをつけて宣言し、型に名前をつけます。

type Person = {
    name: string
    age: number
}

一方、インターフェイス(interface)も型エイリアスと同様に型に名前をつける方法の1つになります。
インターフェイスは以下のように、interfaceをつけて宣言し、型に名前をつけます。

interface Person {
    name: string
    age: number
}

違いは何?

小さい違いになりますが、以下の3つがあります

  • 型エイリアスは右辺に形状以外に型の式が定義できる。
  • インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックする
  • intefaceには、宣言のマージと呼ばれる機能がある。

上記の3つの違いを1つ1つみていきます!

型エイリアスは右辺に形状以外に型の式が定義できる

型エイリアスは、形状以外にも型の式を定義でき、インターフェイスより汎用的に型を定義できます。
型の式とは、型と「&」や「|」のような型演算子になります。

例えば以下のような型は、インターフェイスでは定義できません。

type TypeA = number
type TypeB = string | number
type TypeA = string[]

インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックをする

インターフェイスは、以下のように拡張する場合、拡張元が拡張先に割り当て可能かどうかのチェックが行われ、割り当てができない場合コンパイル時にエラーが吐かれます。

interface TypeA {
    name: string
    age: number
}

// エラーになる
// Types of property 'name' are incompatible.
interface TypeB extends TypeA {
    name: string | number
    age: number
}

一方、型エイリアスの場合は、拡張元の型と拡張先の型が結合されて、うまい具合に上書かれるためエラーにはなりません。

type TypeA = {
    name: string
    age: number
}

// エラーにならない
// nameの型が、`string`から`string | number`に上書かれる。
type TypeB = TypeA & {
    name: string | number
    age: number
}

intefaceは同じスコープ内で同じ名前が複数存在する場合は、自動的にマージされる

インターフェイスには、宣言のマージと呼ばれる機能があり、同じスコープ内で同じ名前が複数ある場合、自動的にマージされるようになっています。

interface Type {
    name: string
}

interface Type {
    name: string
    age: number
}

interface Type {
    address: string
}

// エラーにならず、Typeの型は宣言のマージによりマージされ、
// `name: string`と`age: number`、`address: string`を持つオブジェクトの型になる

一方、型エイリアスでは同じスコープ内で同じ名前が複数ある場合、コンパイル時にエラーになります。

// Duplicate identifier 'Type'. とエラーが出る
type Type = {
    name: string
}

// Duplicate identifier 'Type'. とエラーが出る
type Type = {
    name: string
    age: number
}

まとめ

型エイリアスとインターフェイスはできることが似ているが、3つ異なる部分があります

  • 型エイリアスは右辺に形状以外に型の式が定義できる。
  • インターフェイスを拡張する場合、拡張元が拡張先に割り当て可能かどうかチェックする
  • intefaceには、宣言のマージと呼ばれる機能がある。

上記の違いを踏まえて、今後、Typescriptの開発をしていく中で、どういうケースでどっちを使うべきかを意識しながら、自分なりのベストプラクティスを見つけていきたいと思います!

Discussion

ログインするとコメントできます