TypeScriptのあれこれ⑦ 型の特定のプロパティだけ必須化したい!

はじめに

皆さんこんにちは。エンジニアの細川です。

皆さんはTypeScriptで開発を行っていたときに、型の特定のプロパティだけ必須にしたいと思ったことはありませんか?

例えば以下のようなHuman型を考えてみます。

type Human = {
	name: string;
	age: number;
	phoneNumber?: number
	email?: string;
}

このHuman型のphoneNumberを必須にした型をが欲しいときに、いちいち以下のように全プロパティを定義しなおすのは面倒です。

type HumanRequiredPhoneNumber = {
	name: string;
	age: number;
	phoneNumber: number
	email?: string;
}

このような場合に利用できるUtility型の作り方を紹介します。

指定したプロパティを必須にするユーティリティ型を作成

ある型の特定のプロパティを必須にするには以下のようなユーティリティ型を用意します。

/**
* Tのうち、Kで指定されたプロパティを必須にする
*/
type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

使い方は以下の通りです。

先ほどと同じようにHuman型のphoneNumberを必須にしたい場合は以下のように書きます。

type HumanRequiredPhoneNumber = MakeRequired<Human, "phoneNumber">

このように第1引数に型名、第2引数に必須化したいプロパティ名を書くことで、以下のようにphoneNumberが必須になっていることを確認できます。

また、emailも必須にしたい場合は以下のように定義すればOKです。

type HumanRequired = MakeRequired<Human, "phoneNumber" | "email">

こうすると、phoneNumberに加えてemailも必須にすることができます。

null許容も除外したい場合

上記の型を利用すればoptionalなプロパティを必須にできるのですが、場合によってはnull許容のプロパティを必須にしたい場合もあるかと思います。

以下のようなHuman型からHumanRequiredNotNull型を作るような場合を考えます。

type Human = {
  name: string;
  age: number;
  phoneNumber?: number | null;
  email?: string | null;
}

↓

type HumanRequiredNotNull = {
  name: string;
  age: number;
  phoneNumber: number;
  email: string
}

この場合は以下のようなユーティリティ型を用意します。

/**
 * Tのうち、Kで指定されたプロパティを必須にし、nullを除去する
 */
type MakeRequiredNonNullable<T, K extends keyof T> = Omit<T, K> & Required<{ [P in K]: NonNullable<T[P]> }>;

使い方は先ほどと同様に一つもしくは複数のプロパティを指定して、必須かつnull許容では無いプロパティにすることができます。

type HumanRequiredNotNull = MakeRequiredNonNullable<Human, "phoneNumber" | "email">

実装してみると以下のようにエラーが出るようになります。

まとめ

  1. オプショナルなプロパティを必須にしたい場合は以下
    /**
     * Tのうち、Kで指定されたプロパティを必須にする
     */
    type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
    
    // 利用する場合
    type HumanRequired = MakeRequired<Human, "phoneNumber" | "email">
    const taro: HumanRequired = {
    	name: "taro",
    	age: 20,
    	phoneNumber: 00000000000,
    	email: "xxx@xxx.com"
    }
  2. null許容かつオプショナルなプロパティを必須にし、nullを除外したい場合は以下
    /**
     * Tのうち、Kで指定されたプロパティを必須にし、nullを除去する
     */
    type MakeRequiredNonNullable<T, K extends keyof T> = Omit<T, K> & Required<{ [P in K]: NonNullable<T[P]> }>;
    
    
    // 利用する場合
    type HumanRequiredNotNull = MakeRequiredNonNullable<Human, "phoneNumber" | "email">
    const taro: HumanRequiredNotNull = {
      name: "taro",
      age: 20,
      phoneNumber: 00000000000,
    	email: "xxx@xxx.com"
    }

おわりに

今回は既存の型の特定のプロパティのみを必須にする型を紹介しました。

パッケージなどによって作られる型などは特に再定義するのが面倒なことも多いと思うので少しでも皆さんの役に立てば幸いです。

ちなみに紹介した型の中で利用している、OmitやRequiredなどは事前にTypeScriptに用意されているユーティリティ型です。便利なものも多いので気になる方はこちらでどんな型があるか調べてみてください。

他にもTypeScriptのあれこれを紹介していますので、ぜひ他の記事も見てみてください!

 

 

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です