Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

This post is Private. Only a writer or those who know its URL can access this post.

posted at

TypeScriptの型パターンマッチング

TypeScriptの型パターンマッチング

by Quramy
1 / 10

今日のお題

TypeScript 2.8に入る機能のお話

型のパターンマッチングができるようになる


1. Conditional Types

読んで字の如く、型定義における条件分岐

type MyCondition<T, U, X, Y> = T extends U ? X : Y;

「TがUに代入可能であればXを、そうでなければY」という型


誕生した背景


差分の表現方法

Conditional Typesは、Union Typesについて、分配律が成立

(T1 | T2) extends U ? X : Y = (T1 extends U ? X : Y) | (T2 extends U ? X : Y)

この性質とneverを組み合わせると、差分や絞込が簡単に表現できる

type Diff<T, U> = T extends U ? never : T;

type Result = Diff<("hoge" | "foo" | "piyo"), "foo">
// "hoge" | never | "piyo" = "hoge" | "piyo"

和型、ボトム型、条件型で差分型が表現できた、ということ


ちなみに keyof, Mapped typesと組み合わせると...

type Diff<T, U> = T extends U ? never : T;
type $Diff<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] };
type Props = { name: string, age: number };
type DefaultProps = { age: number };
type RequiredProps = $Diff<Props, DefaultProps>;

declare function setProps<T extends RequiredProps>(props: T): void;

setProps({ name: "foo" });
setProps({ name: "foo", age: 42 }); // you can pass extra props too
setProps({ age: 42 }); // error, name is required

再帰型の終端指定

Mapped Typesによる再帰型で「終端」が表現可能に

type primitive = string | number | boolean | undefined | null;
type DeepReadonly<T> = T extends primitive ? T : DeepReadonlyObject<T>;
type DeepReadonlyObject<T> = {
    readonly [P in keyof T]: DeepReadonly<T[P]>;
};


これだけでも割とすごい


2. Type Inference in Conditional Types

infer でマッチした型をキャプチャできる

type ReturnType<T> = T extends ((...args: any[]) => infer R) ? R : never;
type ResolvedType<T> =
  T extends Promise<infer R> ? R :
  T extends Observable<infer R> ? R :
  T;

所感

  • おそらく、日常使いするものではなさそう
  • 既存ライブラリの型定義を書くときに捗りそう

それでは楽しい型ライフを :angel:

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
Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What are the problem?