0
1

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.

オブジェクトから特定の型のメンバだけを抽出する型関数を作る

Last updated at Posted at 2021-12-30

※PickFromValueTypeの実装をコメントで教えていただいたものに変えました。感謝

オブジェクトから特定の型のメンバだけを抽出する型関数が必要になったのでメモ。
オブジェクトから関数だけ抜いたりできる。
vuexの型付けをするときとかに使えそう。

.ts
/**
 * 指定した型のvalue一覧をunion typeにして返す
 */
type ValueOf<T> = T[keyof T]
/**
 * valueの型を指定し、Targetのvalueの中でその型に一致するkeyの一覧をunion typeとして返す
 */
type KeysFromValueType<Target, Type> = ValueOf<{[key in keyof Target]: Target[key] extends Type ? key : never}>
/**
 * valueの型を指定し、Targetのvalueの中でその型に一致するkeyのみをPickした型を返す
 */
type PickFromValueType<Target, Type> = {[key in keyof Target as Target[key] extends Type ? key : never]: Target[key]};


const obj = {
    id: 0,
    name: '名前',
    func(){},
    asyncFunc(){
        return new Promise(resolve => setTimeout(resolve,100))
    }
}

// number型の値をもつkeyだけ抜き出す
type numbersKey = KeysFromValueType<typeof obj,number> // => "id"
// 関数型の値を持つkeyだけ抜き出す
type FuncKeyOfObj = KeysFromValueType<typeof obj,Function> // => "func" | "asyncFunc"
// 非同期関数だけを抜き出す
type AsyncFuncKeyOfObj = KeysFromValueType<typeof obj,(...args:unknown[]) => Promise<unknown>> // => "asyncFunc"

// numberだけをPickする
type numbers = PickFromValueType<typeof obj,number> // => { id: number }
// 関数型だけをPickする
type Funcs = PickFromValueType<typeof obj,Function> // => { func: () => void, asyncFunc: () => Promise<unknown> }
// 非同期関数だけをPickする
type AsyncFuncs = PickFromValueType<typeof obj,(...args: unknown[]) => Promise<unknown>> // => { asyncFunc: () => Promise<unknown> }

もっと良い書き方あるかも
以上

0
1
4

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?