0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

[TypeScript]TypeとInterfaceはどっちを使うのがいいのか

Last updated at Posted at 2023-07-15

はじめに

型定義では主にTypeとInterfaceが使われますが、どっちを使うのがいいのか、2つの違いについて調べたので書いていきます。

参考

サバイバルTypeScriptを参考にしたので、よければこちらもご覧ください。
サバイバルTypeScript

2つの違いについて

まずは2つの違いについて書いていきます。

Type(型エイリアス)

・継承不可(ただし、&を使えば似たようなことができる)
・継承による上書きができる。
・同名の型定義はできない。
・MappedTypesが使えない。

Interface

・継承可能
・継承による上書きができない。
・同名の型が定義できる。
・MappedTypesが使えない。

継承について

Interfaceは以下のように、型エイリアスを継承できる。

interface Animal {
  name: string;
}
type Creature = {
  dna: string;
};
interface Dog extends Animal, Creature {
  dogType: string;
}

しかし、Typeは継承ができないが、その代わりに&を使えば、似たようなものはできる。

type Animal = {
  name: string;
};
type Creature = {
  dna: string;
};
type Dog = Animal &
  Creature & {
    dogType: string;
  };

継承による上書きについて

継承時のパラメータの上書きは、Interfaceはできますが、Typeはできないです。

Interfaceの継承

interface Animal {
  name: any;
  price: {
    yen: number;
  };
  legCount: number;
}
 
interface Dog extends Animal {
  name: string;
  price: {
    yen: number;
    dollar: number;
  };
}
 
// 最終的なDogの定義
// nameの型とpriceの中身が書き換えられ、dollerも追加されています。
interface Dog {
  name: string;
  price: {
    yen: number;
    dollar: number;
  };
  legCount: number;
}

Typeの継承

type Animal = {
  name: number;
  price: {
    yen: number;
    dollar: number;
  };
};
 
type Dog = Animal & {
  name: string;
  price: {
    yen: number;
    euro: number;
  };
};
 
// 最終的なDogの定義
type Dog = {
  name: never; // 同じ名前のパラメータを定義すると、never型になる。エラーにはならない。
  price: {
    yen: number;
    dollar: number;
    euro: number;
  };
};

同名の型定義について

Interfaceは定義できますが、Typeはできません。

Interfaceは定義できますが、指定した型が違うとエラーになってしまいます.
エラーの理由は、最初はsameNameSameTypeIsAllowedの型をnumberに指定したのに、次に再定義したときはstring型で定義しているためです。

interface SameNameInterfaceIsAllowed {
  myField: string;
  sameNameSameTypeIsAllowed: number;
  sameNameDifferentTypeIsNotAllowed: string;
}
 
interface SameNameInterfaceIsAllowed {
  newField: string;
  sameNameSameTypeIsAllowed: number;
}
 
interface SameNameInterfaceIsAllowed {
  sameNameDifferentTypeIsNotAllowed: number;
// エラー↓
Subsequent property declarations must have the same type.  Property 
'sameNameDifferentTypeIsNotAllowed' must be of type 'string', but here has type 'number'.
}

Typeは同名のものを定義した時点でエラーになります。

type SameNameTypeWillError = {
// エラー↓
Duplicate identifier 'SameNameTypeWillError'.
  message: string;
};
type SameNameTypeWillError = {
// エラー↓
Duplicate identifier 'SameNameTypeWillError'.

MappedTypesについて

これについての説明は省きます。以下のページで詳しく説明されています。
https://typescriptbook.jp/reference/type-reuse/mapped-types

使い分けについて

これについては明確な正解はないそうです、、、
それぞれのメリット、デメリットを理解した上で
プロジェクトや所属するチームのルールに則るしかないようです。
個人的には、Typeのほうが安全かなと思っています。
理由としては、同名の定義ができないので、誤って同じ名前で宣言をしてしまってもエラーが出るので、バグに繋がることを防げるからです。

最後に

他にも記事を書いているので、良ければ見ていってください。

基本設計について
Vue.jsとNode.jsでチャットアプリを作った
Next.js×TypeScriptでTODOアプリを作成する

0
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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?