2021/08/13

interfaceとtypealiasの違いを理解する。

@ 酒井悠宇

TypeScript

コピーサイト作成の進捗報告から

初めに、UnBlogのコピーサイト作成は現在こんな感じです。↓
https://micro-cms-3hzpij77n-sakai-141014.vercel.app/blog/ku00q5qnb

※ブログ本文のスタイル適用はガチモンUnBlogのソースコードから拝借しました。ゲヘヘ。いつか自分でスタイル当てます!

開発環境では数値のpropsが問題なく渡せてビューに反映されているのに、本番環境では反映されていない挙動が起きて悩んでます。

投稿に関連づけられているタグを表示しているここのところですね。

こんな感じでpropsを渡しています。

<RelatedTags data={data} marginTop={2} />

dataは投稿の情報ですね。tagの情報が配列で格納されているのでmapで反復処理を行って表示してます。
そしてタグが多くなったときに若干タグとタグの間のスペースを開けたかったので、marginTopを数値としてpropsで渡しています。
これが開発環境では問題なく反映されてるけど本番環境では反映されない...
なんでだ~!!

てか今気づいたけどボタンが表示されてないところがある...(°_°)
なんで本番環境なった途端表示されなくなんの!せめてエラー出して!

まぁ一旦置いといて本題に入ります。

interfaceとtypealiasの違い


今日はTypeScriptでオブジェクトの型を定義する際に使用するinterfaceと型エイリアス(type alias)の違いについて勉強していきたいと思います。

interface での型定義はこんな感じ

interface Test {
  name: string;
  age: number;
}


typealias での型定義はこんな感じ

type Test = {
  name: string;
  age: number;
}


2021年時点のバージョンで、interface と typealiasは、「できることの多さ」と言う視点で見ると、大差はないようです。

特徴の違いとしては、interfaceはtypealiasよりも拡張性があるというところです。

具体的な例で言うと、interfaceは同名の型を宣言すると宣言が追加(マージ)されますが、typealiasは同名の型を定義するとエラーが出ます。

結論から言うと、ライブラリ開発などの不特定多数が利用する物に関しては拡張性を持たせるためにinterface。
アプリケーション等の全ての型が拡張性を持つとバグを生むような物に関してはtypealiasを使用するのがいい。
といったような感じになるようです。

それではinterfaceやtypeがどのような物なのかを見ていきましょう。

intefaceの基本的な使い方と宣言のマージ


interface宣言子で定義することができます。

interface Person {
  name: string;
}

classの宣言と似たような書き方ですね。

同じ名前のinterfaceを宣言すると型が追加(マージ)されます。
(name: string; age: number; にしたつもりだったけど逆になってましたすんまそん)

こんな感じで型を定義すると...

nameとageのプロパティがないよ!と怒られました。
型の宣言がきちんとマージされている証拠ですね。

typealiasで型のマージを表現


typealiasでも交差型(union型)を使えば型のマージを表現できます。
同名の型は定義できないのでそこは注意が必要です。

interfaceの拡張(継承)


extendsを使用することで、あるinterfaceを拡張したサブinterfaceを作ることができます。
マージとの違いは継承元のinterfaceが変更されるわけではないので使い回しが効く点ですかね。

typealiasを拡張してinterfaceを作る


extendsを使用したinterfaceの拡張ですが、実はtypealiasを継承元とすることもできます。

implementsを使ってinterfaceでclassに型を定義する


interfaceでclassの型を定義することもできます。

typealiasとは?


型に名前をつける為 」に使用するもの。

同名の型を宣言するとエラーが起きたり、継承ができなかったり、そういった「拡張しにくい」と言う特徴を持つtypealiasは「型に名前をつける為」に使用するのがいいですね。この不便さがバグを生み出しにくいという利点を生んでいると思います。ちなみにtypealiasはオブジェクトや関数以外のプリミティブ、配列、タブルでも型宣言が可能です。

Interfaceとは?


オブジェクト、クラス、関数の「構造を定義する為 」に使用するもの。

同名の型を宣言するとマージ(追加)されたり、extendsによる型の継承ができたり、そういった「拡張しやすい」と言う特徴を持つinterfaceは、その拡張のしやすさを存分に生かすために、オブジェクトやクラス、関数の「構造」を定義する為に使用するのがいいですね。自分の中では、typeよりinterfeceの方が抽象的?なイメージです。ちなみにinterfectが定義できるのは、オブジェクトや関数の型のみです。

どっちを使えばいいの?


最初に言いましたが、ライブラリ開発などの不特定多数が利用する物に関しては拡張性を持たせるためにinterface。
アプリケーション等の全ての型が拡張性を持つとバグを生むような物に関してはtypealiasを使用するのがいい。

時と場合によるみたいな感じですね。
自分がライブラリ開発を行うことがほぼないと思うので、アプリケーションを作る機会が多い方は意図しない拡張を防ぐために基本的にはtypeを使用するのが良いのではないでしょうか。

と言うわけで今日はtypeとinterfaceについて勉強してみました。

両者の違いは「拡張のしやすさ」にあることが知れていい感じです。
では次の記事でお会いしましょ〜!ありがとうございました!

© 2021 powerd by UnReact