TypeScript

【TypeScript入門】基本的なユーティリティ型15選!コードを用いて徹底解説

こんにちは、アプリ開発者のテルです!

本記事では、TypeScriptにおける「基本的なユーティリティ型」をご紹介します。

どれも初学者向けに「シンプルで分かりやすい」にこだわって解説しています。

厳選した15選は、TypeScriptを用いたWeb開発には欠かせない知識です。基礎をしっかりと押さえて開発の幅を広げていきましょう。

テル

ぜひ参考にしてみてください!!

本記事を読むメリット
  1. TypeScriptの基本的なユーティリティ型を一覧で確認できる
  2. コードを用いて解説しているため、すぐに理解できる

TypeScriptにおける基本的なユーティリティ型15選

Partial

// 特定の型をオプショナルなものに自動変換する

type Profile = {
  name: string;
  age: string;
};

type PartialType = Partial<Profile>;
// type PartialType = {
//   name?: string | undefined;
//   age?: string | undefined;
// };

Required

// 特定の型を必須なものに自動変換する

type Profile = {
  name?: string;
  age?: string;
};

type RequiredType = Required<Profile>;
// type RequiredType = {
//   name: string;
//   age: string;
// };

Readonly

// 全ての型に[readonly]を付ける

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

type PersonalDataType = Readonly<Profile>;
// type PersonalDataType = {
//     readonly name: string;
//     readonly age: number;
// }

Mapped Types

// Mapped Types (1つずつプロパティを取り出して評価し、新たに別のオブジェクトを生成する)
// [Partial] [Required] [Readonly] は [Mapped Types] によって作られている 

// ①[keyof T] = プロパティの型を文字列リテラル型のユニオン型として取得する
// ②[P in] = Tの各要素を1つずつ取り出し、取り出した要素の型を[P]に指定する
// ③[T[P]] = TにPを代入し、全てを足し合わせたオブジェクトを生成する

// Partialの実体 
type Partial<T> = {
    [P in keyof T]?: T[P];  //Mapped Types
};


// Requiredの実体
type Required<T> = {
    [P in keyof T]-?: T[P];
};

// Readonlyの実体
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

Record

// Record<Keys, Type> (同じような構造のデータを複数のメンバに設定する場合に使用する)

type Pirates = "Rufy" | "Zoro" | "Sanji";

type PiratesInfo = {
  position: string;
  age: number;
};

// Recordを使わなかった場合
const pirates1: {
  Rufy: PiratesInfo;
  Zoro: PiratesInfo;
  Sanji:PiratesInfo;
} = {
  Rufy: { position: "船長", age: 19 },
  Zoro: { position: "剣士", age: 21 },
  Sanji: { position: "料理人", age: 21 },
};

// Recordを使った場合 
const pirates12: Record<Pirates, PiratesInfo> = {
  Rufy: { position: "船長", age: 19 },
  Zoro: { position: "剣士", age: 21 },
  Sanji: { position: "料理人", age: 21 },
};

Exclude

// Exclude <全体の型, 除外したい型> (不要な型を除外する)
type DebugType = () => void;
type SomeTypes = string | number | DebugType;

// [string型]と[number型]を除外している
type FunctionType = Exclude<SomeTypes, string | number>;

// 除外したい型を[Function]にすることで、全ての関数の型を除外する
type TypeExcludingFunction = Exclude<SomeTypes, Function>; 

Extract

// Extract <全体の型, 抽出したい型> (型を抽出する)
type DebugType = () => void;
type SomeTypes = string | number | DebugType;

// [string型]と[number型]を抽出する
type NonFunctionTypeByExtract = Extract<SomeTypes, string | number>;

// 抽出したい型を[Function]にすることで、全ての関数の型を抽出する
type FunctionTypeExtractingFunction = Extract<SomeTypes, Function>; 

NonNullable

// NonNullable <全体の型>  ([null型]と[undefined型]を除外する)
type NullableTypes = string | number | null | undefined;
type NonNullableTypes = NonNullable<NullabelTypes>;

Conditional Types

// Conditional Types (TとUを比較して、真だったらneverを返す|偽だったらTを返す)
// [Exclude] [Extract] [NonNullable] は [Conditional Types]によって作られている

// Excludeの実体
type Exclude<T, U> = T extends U ? never : T; //Conditional Types

 // Extractの実体
type Extract<T, U> = T extends U ? T : never;

// NonNullableの実体
type NonNullable<T> = T extends null | undefined ? never : T;

Pick

// Pick <全体の型, 取り出したい型> (必要なメンバだけを取り出す)

type Profile = {
  name: string;
  age: number;
  nationality: string;
};

type SimpleProfile = Pick<Profile, "name" | "age">;
// type SimpleProfile = {
//     name: string;
//     age: number;
// }

Omit

// Omit <全体の型, 除外したい型> (型を除外する)

type Profile = {
  name: string;
  age: number;
  nationality: string;
};

type SimpleProfile = Omit<Profile, "name" | "age">;
// type SimpleProfile = {
//     nationality: string;
// }

ReturnType

// 関数の戻り値の型を取得する

function add(a: number, b: number): number {
  return a + b;
}

type AddType = ReturnType<typeof add>; //[AddTypeの型]が[number型]になる

function increase(a: number, b: number): AddType {
  return a + b;
}

console.log(increase(1, 2));

infer

// infer(戻り値の型を拾い上げる役割を持つ)
// Conditional Types でよく使用される

// ReturnTypeの実体
// ReturnTypeを使った際に、関数であることは約束されているから100%「R」が返ってくる
type MyReturnType<T extends (...args: any) => any> = T extends (
  ...args: any
) => infer R
  ? R
  : any;

Parameters

const debugProfile = (name: string, age: number) => {
  console.log({ name, age });
};

// Parameters (引数の型のみを取り出す)
// 自分が作った型では使わないが、他人が作ったまどろっこしい型を取得するのに向いている
type Profile = Parameters<typeof debugProfile>; //type Profile = [name: string, age: number

// Parametersの実体
// 型推論として「P=引数」を指定しているため、必ず「真」である「P」が返ってくる
type MyParameters<T extends (...args: any) => any> = T extends (
  ...args: infer P
) => any
  ? P
  : never;

ConstructorParameters

class Person {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

type PersonType = typeof Person;

// ConstructorParameters (特定のクラスのコンストラクタの引数を取得する)
type Profile = ConstructorParameters<PersonType>; //type Profile = [name: string, age: number]

// ConstructorParametersの実体
type MyConstructorParameters<T extends new (...args: any) => any> =
  T extends new (...args: infer P) => any ? P : never;

まとめ

今回は「TypeScriptにおける基本的なユーティリティ型」をご紹介しました。

今回ご紹介した15選は、TypeScriptを用いたWeb開発には欠かせない知識になっています。基礎をしっかりと押さえて開発の幅を広げていきましょう。

TypeScriptを本格的に学びたい場合は「Udemy」がおすすめです。私も含め、現役エンジニアの多くが技術のキャッチアップに利用しています。

▼TypeScript学習におすすめのUdemy講座はこちら

本記事が参考になっていれば幸いです。

最後までご覧いただきありがとうございました。ではまた!

参考:https://www.typescriptlang.org

エンジニア就活対策