Type inference in conditional types
この宣言で、新たな型引数 R
が導入される
genericsの引数に指定せずに、新たな型引数を導入できる
(右辺の)
extends
の右辺にしか書けないことに注意する

(右辺の) extends
の右辺にしか書けないことに注意する
だから例えば、
tstype Hoge<ここには書けない> = ..
type Hoge<T extends ここには書けない> = ..
type Hoge<..> = ここには書けない extends .. ? .. : ..
type Hoge<..> = .. extends ここに書ける ? .. : ..
もっと具体的には、
ts// ok
type Head<T extends any[]> = T extends [any, ...any[]] ? T[0] : never;
// inferはgenericsの話ではないのでng
type Head<T extends any[], [infer H, ...any[]] extends T> = H
// conditional typesだけど、extendsの左辺で使っているのでsyntax error
type Head<T extends any[]> = [infer H, ...any[]] extends T ? H : never
例
ts// 複数使用できる
type Function<F> = F extends (...args: infer A) => infer R ? [A, R] : never;
const f = (a: number, b: string) => true;
type F = Function<typeof f>; // [[number, string], boolean]
tstype Array<T> = T extends (infer U)[] ? U : never;
const array = [1, 'hoge', true];
type A = Array<typeof array>; // string | number | boolean
tstype ReturnType<T extends (...args: any[]) => any> = T extends (
...args: any[]
) => infer R
? R
: any;
「関数の戻り値の部分」に R
という名前を付けて、then節のところで再利用している