typescript 中 infer 用法

infer

介绍

  • infer 一般在 extends 子语句中,infer 会引入一个待推断的类型变量 (如 infer R) R可以是任意单词字母

  • 这个推断的类型变量可以在有条件类型的 true 分支中被引用

  • 允许出现多个同类型变量的 infer。

基本示例

type ParamType<T> = T extends (arg: infer R) => any ? R : T;
type s = ParamType<string>;
type n = ParamType<(id: number) => void>;
type o = ParamType<{ id: number }>;

在这里插入图片描述
在这里插入图片描述
typescript 中 infer 用法_第1张图片

在这个条件语句 T extends (arg: infer R) => any ? R : T; 中,infer R 表示待推断的函数参数。

整句表示为:如果 T 能赋值给 (arg: infer R) => any,则结果是 (arg: infer R) => any 类型中的参数 R,否则返回为 T。

内置类型

提取函数类型的返回值类型

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

// type n = number
type n = ReturnType<() => number>;

// type s = string
type s = ReturnType<() => string>;

在协变位置上,同一个类型变量的多个候选类型会被推断为联合类型

type Foo<T> = T extends { a: infer U, b: infer U } ? U : never;
type T10 = Foo<{ a: string, b: string }>;  // string
type T11 = Foo<{ a: string, b: number }>;  // string | number

在抗变位置上,同一个类型变量的多个候选类型会被推断为交叉类型

type Bar<T> = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never;
type T20 = Bar<{ a: (x: string) => void, b: (x: string) => void }>;  // string
type T21 = Bar<{ a: (x: string) => void, b: (x: number) => void }>;  // string & number

infer 类型参数上的 extends 约束

返回元组类型的第一个元素如果它类似 string 类型的话

type FirstIfString<T> =
    T extends [infer S, ...unknown[]]
        ? S extends string ? S : never
        : never;

 // string
type A = FirstIfString<[string, number, number]>;

// "hello"
type B = FirstIfString<["hello", number, number]>;

// "hello" | "world"
type C = FirstIfString<["hello" | "world", boolean]>;

// never
type D = FirstIfString<[boolean, number, string]>;

你可能感兴趣的:(typescript,typescript,javascript,前端)