MyDocs

# TypeScriptのUtility Types

Partial<Type>

Partial<Type> で指定した型に一時的に切り替えることができる。値を返すときはキャストする必要がある。

interface Todo {
  title: string;
  desc: string;
  date: Date;
}

function createTodo(
  title: string,
  desc: string,
  date: Date,
): Todo {
  // let todo: Todo = {} // ここでのエラーを防ぐ
  let todo: Partial<Todo> = {};
  todo.title = title;
  todo.desc = desc;
  todo.date = date;
  return todo as Todo;
}

Required<Type>

パラメータが欠損したらエラー。

interface Todo {
  title: string;
  desc: string;
  date: Date;
}

function createTodo(
  title: string,
  desc: string,
  date: Date,
): Todo {
  const todo: Required<Todo> = {
    title: title,
    desc: desc,
    date: date,
  };

  return todo;
}

Readonly<Type>

初期化したあとにパラメータを変更できないようにする。

interface Todo {
  title: string;
}

const todo: Readonly<Todo> = {
  title: "create",
};

// todo.title = "update"

Record<Keys, Type>

Key とその型を指定できる。辞書として使いたい場合に適している。

interface CatInfo {
  age: number;
  breed: string;
}

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

console.log(cats);
// {
//   miffy: { age: 10, breed: "Persian" },
//   boris: { age: 5, breed: "Maine Coon" },
//   mordred: { age: 16, breed: "British Shorthair" }
// }

console.log(cats.boris);
// { age: 5, breed: "Maine Coon" }

Pick<Type, Keys>

keys に指定したプロパティの型になる。

interface Todo {
  title: string;
  desc: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

Omit<Type, Keys>

keys に指定した以外のプロパティの型になる。

interface Todo {
  title: string;
  desc: string;
  completed: boolean;
  createdAt: number;
}

type TodoPreview = Omit<Todo, "desc">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  createdAt: 1000,
};

Exclude<Type, ExcludedUnion>

Exclude<T, U> T から U を除いた型になる。

type T0 = Exclude<"a" | "b" | "c", "a">;
// type T0 = "b" | "c"

type T1 = Exclude<"a" | "b" | "c", "a" | "b">;
// type T1 = "c"

type T2 = Exclude<string | number | (() => void), Function>;
// type T2 = string | number

Extract<Type, Union>

Extract<T, U> T と U のユニオン型になる。

type T0 = Extract<"a" | "b" | "c", "a" | "f">;
// type T0 = "a"

type T1 = Extract<string | number | (() => void), Function>;
// type T1 = () => void

NonNullable<Type>

nullundefined を除いた型になる。

type T0 = NonNullable<string | number | undefined>;
// type T0 = string | number

type T1 = NonNullable<string[] | null | undefined>;
// type T1 = string[]

Parameters<Type>

Parameters<T> では T は関数型の必要がある。 T が関数のとき T の引数一覧をタプル型で作成する。

declare function f1(arg: { a: number; b: string }): void;

type T0 = Parameters<() => string>;
// type T0 = []

type T1 = Parameters<(s: string) => void>;
// type T1 = [s: string]

type T2 = Parameters<<T>(arg: T) => T>;
// type T2 = [arg: unknown]

type T3 = Parameters<typeof f1>;
// type T3 = [arg: {
//   a: number;
//   b: string;
// }]

type F = (arg1: string, arg2: number) => string;
type F1 = Parameters<F>;
// type F1 = [arg1: string, arg2: number]

const v: F1 = ["a", 123];

ConstructorParameters<Type>

class のコンストラクタ関数の引数の型からタプル型を作成する。

type T0 = ConstructorParameters<ErrorConstructor>;
// type T0 = [message?: string]

type T1 = ConstructorParameters<FunctionConstructor>;
// type T1 = string[]

class Person {
  constructor(public id: number, public name: string) {}
}

type P = ConstructorParameters<typeof Person>;
// type P = [id: number, name: string]

ReturnType<Type>

戻り値からなる型になる。

declare function f1(): { a: number; b: string };

type T0 = ReturnType<() => string>;
// type T0 = string

type T1 = ReturnType<(s: string) => void>;
// type T1 = void

type T2 = ReturnType<<T>() => T>;
// type T2 = unknown

type T3 = ReturnType<<T extends U, U extends number[]>() => T>;
// type T3 = number[]

type T4 = ReturnType<typeof f1>;
// type T4 = {
//   a: number;
//   b: string;
// }

InstanceType<Type>

コンストラクタの戻り値からなる型。

class C {
  x = 0;
  y = 0;
}

class Foo {}

type T0 = InstanceType<typeof C>;
// type T0 = C

type T1 = InstanceType<typeof Foo>;
// type T1 = Foo

ThisParameterType<Type>

関数型の this パラメータの型を抽出した型になる。

function toHex(this: number) {
  return this.toString();
}

function numberToString(n: ThisParameterType<typeof toHex>) {
  return toHex.apply(n);
}

console.log(numberToString(123));
// 123

OmitThisParameter<Type>

関数型の this パラメータの型を除いた型になる。

function toHex(this: number) {
  return this.toString();
}

const fiveToHex: OmitThisParameter<typeof toHex> = toHex.bind(123);

console.log(fiveToHex());
// 123

ThisType<Type>

オブジェクト内の this の型を正しい型にする。

interface User {
  name: string;
}

interface Greeting {
  hello(): void;
}

const user: Greeting & ThisType<User> = {
  hello() {
    console.log(`Hello ${this.name}`);
  },
};