LoginSignup
5
3

More than 1 year has passed since last update.

【TypeScript】ある型から変数プロパティを抽出するUtility Types

Posted at

TypeScriptで実装をしてると、特定の型の変数プロパティだけ抽出した型を指定したくなることがたまにあります。
そういうときに使えるUtility Typesをつくりました。

前提

例えば次のようなクラスAがあって、コンストラクタの引数は自身と同じインターフェイスを持つオブジェクトにしたいとき、クラスAの持つメソッドも引数に指定しないといけません。

class A {
  a: string;

  constructor(v: A) {
    this.a = v.a;
  }

  func () {
    //
  }
}

const c = new A({
  a: 'a',
  func: () => {}, // これはよくないので無くしたい
});

でもメソッドまで実際の引数に指定するのは無駄なので、メンバ変数だけを指定したくなります。
このクラスAの場合はメンバ変数が1つなので

  constructor(v: { a: string }) {

このようにコンストラクタを指定してもいいですがメンバ変数が増えていくと辛い…
さてどうしましょ。

Utility Typesを定義する

Utility TypesでクラスAからメンバ変数のaだけを抽出するようなものを実装します。

type NonFuncPropNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];

type NonFuncProps<T> = Pick<T, NonFuncPropNames<T>>;

変数プロパティを抽出すると書いておきながら、実際はジェネリクスで指定された型から関数プロパティを除去してます。
なので名前もNonFuncProps
こまけえこたぁ(略

実装を修正

で、このNonFuncPropsにクラスAを指定すると最初のサンプルは次のように書けます。

class A {
  a: string;

  constructor(v: NonFuncProps<A>) {
    this.a = v.a;
  }

  func () {
    //
  }
}

const c = new A({
  a: 'a',
});

こんな感じでメソッドは書かなくてよくなりました。
これでクラスにたくさんメンバ変数が増えても安心ですね。

もちろんこのUtility Typesはインターフェイスとかにも適用できます。あー便利

5
3
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
3