TypeScript - 継承型
こんにちは、未来のTypeScript魔法使いたち!今日は、Conditional Typesの世界への興味深い旅に出かけます。プログラミングが初めての方でも心配しないでください。私はあなたの親切なガイドとして、ステップバイステップで進めていきます。このレッスンの終わりには、学んだことがどれほど多いかに驚くことでしょう!
基本的な継承型
まずは基本から始めましょう。TypeScriptのConditional Typesは、コード内で決定を行うようなものです。アイスクリーム屋にいるとしまして、天気が暑いかどうかによってチョコレートとバニラのどちらを選ぶ決定を行う、そんな感じです。这正是 TypeScript 中的 Conditional Types 所做的事情!
以下に簡単な例を示します:
type IceCreamChoice = boolean extends true ? "Chocolate" : "Vanilla";
このコードでは、「boolean(trueまたはfalseを表す)がtrueにすることができる場合、Chocolateを選択;さもなければ、Vanillaを選択」と言っています。
でも、booleanは常にtrueにできるじゃないですか?では、もっと実用的にしてみましょう:
type WeatherChoice<T> = T extends "Hot" ? "Ice Cream" : "Hot Chocolate";
let summerChoice: WeatherChoice<"Hot"> = "Ice Cream";
let winterChoice: WeatherChoice<"Cold"> = "Hot Chocolate";
ここでは、WeatherChoice
という型を定義し、型パラメータT
を受け取ります。T
が"Hot"を継承(または一致)する場合、"Ice Cream"を選択;さもなければ、"Hot Chocolate"を選択します。
ジェネリックな継承型
次に、レベルアップしましょう!ジェネリックな継承型は、型をより柔軟かつ再利用可能にします。アイスクリームメーカーが、何を入れるかによって異なるフレーバーを作れる超级 flexibleなものを考えたとすると、そんな感じです。
type IsArray<T> = T extends any[] ? true : false;
type CheckString = IsArray<string>; // false
type CheckNumberArray = IsArray<number[]>; // true
この例では、IsArray
は入力型T
が配列であるかどうかをチェックするジェネリック型です。配列の場合はtrue
を返し、それ以外の場合はfalse
を返します。
もっと複雑なものを試してみましょう:
type ElementType<T> = T extends (infer U)[] ? U : never;
type StringArrayElement = ElementType<string[]>; // string
type NumberArrayElement = ElementType<number[]>; // number
type NotArrayElement = ElementType<number>; // never
ここでは、ElementType
は配列の要素の型を抽出します。T
が配列の場合、要素型U
を推論し、それを返します。T
が配列でない場合、never
(「これは決して起こるべきでない」という意味)を返します。
継承型の制約
時々、型にいくつかの制約を設けたいことがあります。これは、「野菜を食べ終わったらアイスクリームを食べる」と言うようなものです。TypeScriptでの動作を見てみましょう:
type NumberOperation<T extends number> = T extends 0 ? "Zero" : "Non-zero";
type ZeroCheck = NumberOperation<0>; // "Zero"
type NonZeroCheck = NumberOperation<5>; // "Non-zero"
type InvalidCheck = NumberOperation<"5">; // エラー: Type '"5"' does not satisfy the constraint 'number'.
この例では、NumberOperation
はnumber
を継承する型のみを受け入れます。それから、数が0かどうかをチェックします。
継承型内での推論
最後に、継承型内での推論についてお話ししましょう。これは、あなたの気分に基づいてどのフレーバーが欲しいかを把握できる超级 smartなアイスクリームメーカーのようなものです!
type Flatten<T> = T extends Array<infer U> ? U : T;
type FlattenedNumberArray = Flatten<number[]>; // number
type FlattenedString = Flatten<string>; // string
ここでは、Flatten
はT
が配列かどうかをチェックします。配列の場合、要素型U
を推論し、それを返します。それ以外の場合、T
をそのまま返します。
もっと高度なものを試みましょう:
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
function greet(name: string): string {
return `Hello, ${name}!`;
}
type GreetReturn = ReturnType<typeof greet>; // string
この例では、ReturnType
は関数の戻り型を推論します。T
が関数型の場合、戻り型R
を推論し、それを返します。
結論
おめでとうございます!TypeScriptのConditional Typesへの最初の一歩を踏み出しました。自転車に乗るのと同じで、最初は不安定に感じるかもしれませんが、練習を続ければすぐにスムーズに走れるようになるでしょう!
以下は、私たちがカバーした方法の簡単な参照表です:
メソッド | 説明 |
---|---|
基本的な継承型 | 条件に基づいて型の決定を行う |
ジェネリックな継承型 | 柔軟で再利用可能な継承型を作成する |
継承型の制約 | 入力型に制約を設ける |
継承型内での推論 | 条件内で型を抽出し推論する |
練習を続け、好奇心を持ち続けてください。それさえあれば、TypeScriptで素晴らしいことを創造するでしょう。未来のTypeScriptマスターたち、ハッピーコーディング!
Credits: Image by storyset