🤖

TypeScript入門 【ちょっと発展した型定義編】

2021/10/25に公開約2,700字

今回はTypeScriptのちょっと発展した型定義について説明していきます。

型エイリアス vs インターフェース


まずは似ているけれど違う、型エイリアスとインターフェースについて説明していきます。

大きな違いは主に2つです。

まず、インターフェースは拡張に対してオープンな性質を持っています。

2つ目は、型エイリアスはマップ型や条件付き型といった高度な型構文が記述できるけれど、インターフェースではそれができないというところになります。


interface hoge {
  sideA: number;
  sideB: number;
}
// 型が拡張されていく
interface hoge {
  sideC: number;
}
const obj: hoge = {
  sideA: 1,
  sideB: 2,
  sideC: 3
};

type bar = {
  sideA: number;
  sideB: number;
};
// エラー 'bar' is already defined.
type bar = {
  sideC: number;
};

// interfaseにはこの表現はできない
type numbers = 1 | 2 | 3;

この2つは型エイリアスの方が便利で使いやすいので、特に理由がなければ型エイリアスを使えば良いと思います。

後ほど紹介するようにtypeも拡張することは可能ですし。

型の演算子


次に型の演算子について紹介していきます。

これらを使うことで、さらに高度な型を定義できるようになります。

共用体型 ユニオン型

共用体型とは、演算子 | で型を並べることで、それらの内のいずれかの型が適用される複合的な型にさせる方法です。


// 1か2か3が入る
type hoge = 1 | 2 | 3;

type A = {
  foo: number;
  bar?: string;
};
type B = { foo: string };
type C = { baz: boolean };
type AorB = A | B; // { foo: number | string; bar?: string }
type AorC = A | C; // { foo: number; bar?: string } or { baz: boolean }
const typeA: AorB = { foo: "a" };
const typeB: AorB = { foo: 1, bar: "a" };
// エラー Type 'number' is not assignable to type 'string | undefined'.
const typeD: AorB = { foo: 1, bar: 2 };

オブジェクト型も共用体型に適用でき、基本は文字列リテラル型と同じで 単にその並べられたオブジェクトの型のいずれかが適用されるという感じになります。

交差型 インターセクション型

交差型とは演算子&で並べ、『A かつ B』と複数の型をひとつに結合させるものになります。

用途としては、オブジェクト型の合成に使われます。

この時同じ型でありながら必須と省略可能が交差したら、必須のほうが優先されます。

そして、もし同じプロパティで型が共通点のないものだった場合は、never型になります。


type A = { foo: number };
type B = { bar: string };
type C = {
  foo?: number;
  baz: boolean;
};
type AnB = A & B; // { foo: number, bar: string }
type AnC = A & C; // { foo: number, baz: boolean }
type CnAorB = C & (A | B); // { foo: number, baz: boolean } or { foo?: number, bar: string, baz: boolean }

typeof

次にtypeof演算子です。

これは型のコンテキストで用いると、変数から型を抽出してくれます。


const numArr = [1, 2, 3];
// number[]になる
const newArr: typeof numArr = [1];

keyof

次はkeyof演算子です。

これは通常の式では使えず、型コンテキストのみで用いられる演算子になります。

これは文字通りオブジェクトの型からキーを抜き出してくるます。


const permissions = {
  lastName: "hinohara",
  wfirstName: "shinya"
};
type PermsChar = keyof typeof permissions; // 'lastName' | 'firstName'
const readable: PermsChar = "lastName";

このようにtypeof と合わせると、既存のオブジェクトからキーの型を抽出できます。

配列から型を抜き出す。

最後に、配列から型を作る方法を紹介します。


const hoby = ["reading", "traveling"] as const;
type hobytype = typeof hoby[number]; // 'reading' | 'traveling'

このように書くことで配列の要素をリテラル型で使えるよになります。

おわりに


今回はちょっと発展した型定義の方法について見てきました。

ここら辺までを理解できていたら、実務でもやっていけると思います。

忘れたらまたこの記事に戻ってきていただければと思います。

また、僕のブログではReactエンジニアになるためのロードマップを無料で全て公開しているので、参考にどうぞ。バックエンドエンジニアを目指している方などにも役立つ情報を書いてます。

https://hinoshin-blog.com/react-roadmap/

おわり

Discussion

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