♾️

TypeScriptのinferを知ろう

に公開

概要

別記事を書くにあたりinferを理解しようの会

inferとは

Conditional Typesで利用される、型推論の変数を導入するキーワード
参考: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types

Conditional Typesについてはこちらを参照。
また、この後でてくるであろうジェネリクス型についてはこちらを参照。

type Hoge<T> = T extends infer U ? U : never;

let hoge: Hoge<string>; // string型
let fuga: Hoge<"hoge">; // リテラル型 "hoge"

上記の場合は、引数Tから型を推論してUに格納し、推論できる場合はUをそのまま返却、できない場合はnever型を返却する。
Hoge<string>Hoge<"hoge"> も与えられた型がそのまま返却できている。

もうちょっと複雑な例だと

type Name<T> = T extends { name: infer N } ? N : never;

const hoge = { name: "ほげ太郎", message: "こんにちは、ほげ太郎です。" };
const fuga = { name: ["ほげ太郎", "ふが太郎", "ぴよ子"] };
const piyo = { message: "こんにちは、ぴよ子です。" };

type Hoge = Name<typeof hoge>; // リテラル型 "ほげ太郎"
type Fuga = Name<typeof fuga>; // string[]
type Piyo = Name<typeof piyo>; // never

といった感じ。
nameプロパティがある場合はnameプロパティの値に対して型推論ができるのでそれを返却、
nameプロパティがない場合は型推論ができないのでneverを返却しているといった感じ。
※ typeofの説明はこちら

まとめ

一旦推論してそれを変数に入れておきたい、みたいな時に使うと有効的かも。
先ほども言った通り、Conditional Typesの時にしか使用できないので注意。

Discussion