TypeScript の高度な型 ⑨ 再帰的なUtility Types

TypeScript 2.8 以降では、Mapped TypesとConditional Types を併用することで、

 

再帰的な型変換が可能です。

 

今回の記事では紹介する型は、リスト6-3-24に示した既存の型に対して変換を行うものとします。

 

interface User{
 name: string
 age: number
 gender: 'male' | 'female' | 'other'
 birth: {
  day: Date
  place?: {
   countory?: string | null
   state?: string
  }
 }
}

 

isPrimitive型

 

Object型およびArray型に該当するか否かを判定する型です。

 

(該当しなければPrimitive型とみなす)

 

再帰的な型変換に、この型を利用します。

 

type Unbox<T> = T extends {[k: string]: infer U} ? U
                : T extends (infer U)[] ? U
                : T
type isPrimitive<T> = T extends Unbox<T> ? T : never

 

DeeReadonly型

 

再帰的にReadonly変換する型です。

 

type DeepReadonly<T> = {
 reaonly [P in keyof T]: T[P] extends isPrimitive<T[P]>
                       ? T[P]
                       : DeepReadonly[T[P]]
}
type DeepReadonlyWrapUser = DeepReadonly<User>

 

型推論結果

 

type DeepreadonlyWrapUser = {
 name: string
 readonly age: number
 readonlu gender: 'make' | 'female' | 'other'
 readonly birth: {
  readonly day: Date
  readonly place?: {
   readonly countoru?: string : null
   readonly state?: string
 }
}

 

DeepRequired型

 

再帰的にRequired変換する型です。

 

type DeepRequired<T> = {
 [P in keyof T]-?: T[P] extends isPrimitive<T[P]>
                  ? T[P]
                  : DeepRequired<T[P]>
}
type DeepRequiredWrapUser = Deeprequired<user>

 

推論結果

 

type DeepPartialWrapUser = {
 name?: string| undefined
 age?: number | undefined
 gender? : 'male', 'famale' | 'other' | undefined
 birth?: {
  day? date | undefind
  place? : {
   countory? : string | null | undefined
   state? : string| undefined
  } | underfined
 } | underfined
}

 

DeepNullable型

 

再帰的にNullable変換する型です。

 

type DeepNullable<T> = {
 [P in keyof T]?: T[P] extends isPrimitive<T[P]>
               ? T[P] | null
               : DeepNullable<T[P]>
}
type DeepNullableWrapUser = DeepNullable<user>

 

 

type DeepPartialWrapUser = {
 name?: string| null | undefined
 age?: number | null | undefined
 gender? : 'male', 'famale' | 'other' | null | undefined
 birth?: {
  day? date | undefind
  place? : {
   countory? : string | null | undefined
   state? : string | null | undefined
  } | null | underfined
 } | null | underfined
}

 

DeepNonNullable 型

 

再帰的にNullable変換する型です。

 

type DeepNonNullable<T> = {
 [P in keyof T]-?: T[P] extends isPrimitive<T[P]>
                 ? Exclude<T[P], null | undefinned>
                 : DeepNonNullabel<T[P]>
}
type DeepNoNullableWrapUser = DeepNonNullable<User>

 

型推論結果

 

type DeepNonNullableWrapUser = {
 name: string
 age: number
 gender : 'male', 'famale' | 'other'
 birth: {
  day Date
  place : {
   countory: string
   state: string
  }
 }
}
藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

TypeScript

コメントする

メールアドレスが公開されることはありません。