TypeScript で Infer キーワードを使用する

Migel Hewage Nimesha 2024年2月15日
  1. TypeScript の型推論
  2. TypeScript で infer キーワードを使用する
TypeScript で Infer キーワードを使用する

この記事では、TypeScript での条件付き型の型推論と実装について説明し、デモンストレーションします。 ここでは、infer キーワードの重要性とその使用方法について説明します。

TypeScript の型推論

TypeScript は、JavaScript プログラミング言語の型付きスーパーセットとして知られています。 したがって、TypeScript ユーザーは、次に示すように型に明示的に注釈を付けることができます。

変数:

let numberTypeVariable: number = 2;
let stringTypeVariable: string = 'This is a string';
let booleanTypeVariable: boolean = true;

関数パラメータ:

function addTwoNumbers(numberOne: number, numberTwo: number){
    return numberOne + numberTwo;
}

関数の戻り値の型:

function addTwoNumbers(numberOne: number, numberTwo: number): number{
    return numberOne + numberTwo;
}

これにより、TypeScript はタイプ セーフな言語になり、プログラマーはコンパイル時にエラーを検出できます。 また、変数、関数パラメーター、または戻り値の型に明示的に注釈を付ける必要はありません。

TypeScript は型付き言語であるため、TypeScript コンパイラは適切な型を暗黙的に見つけるのに十分なほどインテリジェントです。 これを型推論と呼びます。

TypeScript は、Best Common Type アルゴリズムを使用して、すべての候補と互換性のある最適な型を選択します。

例:

let stringValueInferred = 'This is a string literal';

出力 (Visual Studio コード):

Typescript 推論 - 出力 1

stringValueInferred 変数には文字列リテラルが割り当てられているため、TypeScript コンパイラはその型を文字列として推測します。

関数パラメーターにデフォルト値を割り当てると、TypeScript コンパイラーも型を推測します。

例:

function addTwoNums(numOne=0, numTwo=0){
    return numOne + numTwo
}

出力:

Typescript 推論 - 出力 2

また、関数の戻り値の型に明示的に注釈を付ける必要はありません。 それも推測済み。

Typescript 推論 - 出力 3

addTwoNums 関数の戻り値の型は、number 型として推測されています。 これは、TypeScript が標準で提供する非常に堅牢な機能です。

TypeScript で条件付き型を実装する

条件付き型は、型推論のもう 1つの強力な機能です。 TypeScript は、指定された条件に基づいて、2つの可能なタイプのいずれかを選択できます。

構文:

type myPreferredType = T extends U ? X : Y

上記の構文の意味は、ある型 T が何らかの型 U に代入可能である場合、真のパス型 X を選択するということです。 それ以外の場合は、タイプ Y を選択します。

それでは、myOwnType という型を作成しましょう。

type myOwnType = number;

次に、myOwnConditionalType という条件付きタイプを作成します。

type myOwnConditionalType = myOwnType extends number? number : any;

出力:

Typescript 推論 - 出力 4

myOwnConditionalType は数値と推論されます。これは myOwnType が数値型であり、与えられた条件 number ? number : any において数値型に代入可能であるためです。

myOwnType を文字列に変更した場合。 次に、myOwnConditionalTypeany 型になります。

出力:

Typescript 推論 - 出力 5

複雑なジェネリック型でも同じ概念が有効です。 ジェネリック型を見てみましょう。

type myStringOrNullType<T> = T extends string ? string : null;

この myStringOrNullType<T> 型を使用して、別のカスタム型を推測します。

type myInferredType = myStringOrNullType<boolean>;

出力:

Typescript 推論 - 出力 6

myInferredTypenull と推論されました。これは、ブール値が文字列型に割り当てられず、指定された条件が false パスをたどり、null が返されるためです。

出力:

Typescript 推論 - 出力 7

T は文字列リテラルになったため、文字列型に割り当てることができます。 したがって、条件は true と評価され、そのパスは文字列型を返します。

TypeScript で infer キーワードを使用する

infer キーワードを使用すると、条件付き型をより柔軟に使用できます。 これにより、ユーザーはある型を全体として、またはその型の一部として推論することができ、場合によっては非常に強力になります。

infer キーワードで新しい型を定義しましょう。

type inferSomeType<T> = T extends infer U ? U : null;

この場合、T 型全体を推論して返します。

type myInferredType = inferSomeType<'This is going to be inferred as the type'>

出力:

Typescript 推論 - 出力 8

これで、myInferredType 型は、infer U 部分から、"This is going to be inferred as the type" として推論されました。 これは、T の型全体を推論したことを意味します。

ここで、型 T の部分を推論できる別の例に注目しましょう。

type inferPartsOfSomeType<T> = T extends { propA: infer TypeA, propB: number } ? TypeA : null;

ここでは、型 T が特定のオブジェクト型に割り当て可能かどうかを確認します。 そのオブジェクトが T と同じ場合、条件は true と評価され、推測された typeA を返します。 それ以外の場合、null を返します。

上記で宣言した型 inferPartsOfSomeType を使用して、inferredType という名前の新しいカスタム型を作成しましょう。

type inferredType = inferPartsOfSomeType<{ propA: 'NewTypeA' }>

上記の場合、T は指定されたオブジェクト { prop1: 'NewTypeA' } に代入できません。これは、このオブジェクト内に別の数値型プロパティがないためです。 したがって、条件は false と評価され、inferredType 値として null を返す必要があります。

出力:

Typescript 推論 - 出力 9

inferPartsOfSomeType で定義されたオブジェクトに同一のオブジェクトを与えましょう - このようなもの。

{ propA: NewTypeA, propB: 500 }

出力:

Typescript 推論 - 出力 10

今回は、新しいオブジェクト { propA: NewTypeA, propB: 500 } は型 T に割り当て可能です。 したがって、条件は true と評価され、propA の型である "NewTypeA" が推測されます。 これは、タイプ T の部分をどのように推測できるかをまとめたものです。

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.

関連記事 - TypeScript Keyword