3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

ネストされたオブジェクトのプロパティをひたすらすべて列挙して、Union Typeにするワンライナー

どこで使えるのかはわからないけれど、ネストされたオブジェクトのプロパティをひたすらすべて列挙して、Union Typeにするワンライナーができたのでメモ

type ValueOf<T> = T[keyof T];
type Property<T> = keyof T | ValueOf<{[K in keyof T]: T[K] extends object ? Property<T[K]> : never}>

ワンライナーといいつつ2行あるのはご愛嬌

以下のような感じで使える

interface User {
  name: string,
  id: string,
  obj: {
    obj2: {
      aaa: string
    },
    bbb: string,
  }
}
type ValueOf<T> = T[keyof T];
type Property<T> = keyof T | ValueOf<{[K in keyof T]: T[K] extends object ? Property<T[K]> : never}>

type UserProperty = Property<User> //=> "name" | "id" | "obj" | "obj2" | "bbb" | "aaa"

image.png

ちなみにネストされているプロパティをチェックしなくて良いなら以下で事足りる

type Property<T> = keyof T //=> "name" | "id" | "obj"

深さ指定で所得できるようにする

もはやワンライナーではないけれど、以下のように書けば深さ指定でプロパティを所得できる


// 5階層まで対応。もっと深くまで辿りたい場合は 6:5 のように増やす
type NumMap = {
    5:4,
    4:3,
    3:2,
    2:1,
    1:1,
}

type ValueOf<T> = T[keyof T];
type Property2<T,P extends keyof NumMap> = P extends 1 ?  keyof T : ValueOf<{[K in keyof T]: T[K] extends object ? Property2<T[K], NumMap[P]> : never}>

以下のように使える

interface User {
  name: string,
  id: string,
  obj: {
    obj2: {
      aaa: string
    },
    bbb: string,
  }
}

type NumMap = {
    5:4,
    4:3,
    3:2,
    2:1,
    1:1,
}

type ValueOf<T> = T[keyof T];
type Property2<T,P extends keyof NumMap> = P extends 1 ?  keyof T : ValueOf<{[K in keyof T]: T[K] extends object ? Property2<T[K], NumMap[P]> : never}>

type UserProperty = Property2<User,2> //=> "obj2" | "bbb"

image.png

まとめ

TypeScriptすごい

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
3
Help us understand the problem. What are the problem?