5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

特定のプロパティだけrequiredにする型を作ってみる

Last updated at Posted at 2021-02-10

はじめに

typescriptには組み込みで、Requiredという型があります。

type Dummy = {
  hoge?: string
  fuga?: string
  bar?: string
}

Required<Dummy>

//{
//  hoge: string
//  fuga: string
//  bar: string
//}

Requiredの第一ジェネリックスに型を入れると、全て必須プロパティにしてくれます。
いわゆるUtility Type ですね。

指定したプロパティだけ必須にしてほしい

組み込みのRequiredでは、全て必須プロパティになってしまいます。

組み込みで駄目ならパッケージを使う?
このためだけにパッケージを入れるのも煩わしい。

そういうときはサクッと自分で実装してしまいましょう。

実装

type Dummy = {
  hoge?: string
  fuga?: string
  bar?: string
}

type Required<T,K extends keyof T> = T & {
  [P in K]-?: T[P]
}

Required<Dummy,"hoge">
//{
//  hoge: string
//  fuga?: string
//  bar?: string
//}

自分で実装したRequiredは第一ジェネリクスに型、第二ジェネリクスに必須にしたいプロパティ名を入れると、特定のプロパティだけ必須にすることができます。

解説

type Required<T,K extends keyof T>

extends keyofはプロパティをジェネリクスとして扱える機能です。
今回の場合はT型に含まれるプロパティをKとしています。

= T & {
  [P in K]-?: T[P]
}

typescriptでinは反復処理を表します。
Require<Dummy,"hoge"|"fuga">のように複数のプロパティが渡された時は、それぞれhoge:stringfuga:stringと処理されることになります。

-??を消去してくれます。

T型と&で結合しています。
必須プロパティと省略可能プロパティを結合すると、必須プロパティが優先されます。

指定したプロパティだけ省略可能プロパティにする方法は?

type PickPartial<T,K extends keyof T> =  Omit<T,K>&{
  [P in K]?: T[P]
} 

Omitで一度プロパティを消去してから、省略可能プロパティを追加しています。

最後に

パッケージを使いたいという方はこちらがおすすめです。
https://github.com/piotrwitek/utility-types

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?