LoginSignup
1
1

More than 5 years have passed since last update.

Mapped typeとConditional typeを使ってclass/interfaceのプロパティの型を変更するサンプル

Posted at

以下のようなコードのContent型のプロパティから、OrFunction内の関数定義のみを取り除いた型(Union型の一部を取り除いた型)を作ることができます。

main.ts
type OrFunction<T> = T | ((val: string) => T);
interface Content {
    id: string;
    id2?: number;
    key: OrFunction<string>;
    value?: OrFunction<boolean>;
    names?: Array<OrFunction<string>>;
    names2: Array<OrFunction<string>>;
    value2?: Array<Array<OrFunction<string>>>;
}

Conditional typesは再帰的定義ができないようなので、Arrayのネスト分の定義が必要になるのが惜しいですが、以下のような定義をしておくと

sample.ts

type Plain<T> = { [P in keyof T]: ExcludeArray<T[P], (val: any) => any> };
type ExcludeArray<T, U> = T extends Array<infer R> ? Array<ExcludeArray2<R, U>> : Exclude<T, U>;
type ExcludeArray2<T, U> = T extends Array<infer R> ? Array<Exclude<R, U>> : Exclude<T, U>;

Plain<Content>は以下のような型になります。

{
    id: string;
    id2?: number;
    key: string;
    value?: boolean;
    names?: Array<string>;
    names2: Array<string>;
    value2?: Array<Array<string>>;
}

Mapped typesは一見難しそうですが、{ [P in keyof T]: T[P] }の基本的な形を覚えておけばOKです。
Conditional typesの導入とともに入ったExclude型は便利ですね。

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