TypeScript 条件类型怎么用?

文章导读
Previous Quiz Next In TypeScript 中,条件类型允许你根据条件为变量分配类型。这使你能够定义根据特定条件动态变化的类型。此功能在大规模应用中非常有用,在这些应用中,你需要根据不同情况进行动态类型定义。
📋 目录
  1. A 基本条件类型
  2. B 泛型条件类型
  3. C 条件类型约束
  4. D 条件类型中的推断
A A

TypeScript - 条件类型



Previous
Quiz
Next

In TypeScript 中,条件类型允许你根据条件为变量分配类型。这使你能够定义根据特定条件动态变化的类型。此功能在大规模应用中非常有用,在这些应用中,你需要根据不同情况进行动态类型定义。

基本条件类型

我们将使用三元(?:)运算符来使用条件类型。它会评估条件,并根据 true 或 false 的结果选择新的类型。

语法

你可以使用以下语法来使用条件类型。

type A = Type extends anotherType ? TrueType : FalseType;
  • 在上述语法中,'Type extends anotherType' 条件将首先被评估。

  • 如果条件为 true,则 'type A' 将包含 'TrueType'。否则,它将包含 'FalseType'。

  • 这里,'extends' 关键字检查 'Type' 是否与 'anotherType' 相同,或者至少包含 'anotherType' 类型的所有属性。

示例

在下面的代码中,我们定义了 'car' 类型,其中包含 name、model 和 year 属性。我们还定义了仅包含 'name' 属性的 'Name' 类型。

'carNameType' 类型变量根据 'Car extends Name' 条件的评估结果存储 string 或 any 值。这里,条件将被评估为 true,因为 'Car' 类型包含 'Name' 类型的所有属性。

之后,我们创建了 'carNameType' 类型的 'carName' 变量,并在控制台中打印它。

type Car = {
    name: string,
    model: string,
    year: number,
}
type Name = { name: string }
// 如果 Car extends Name,则 carNameType 为 string,否则为 any
type carNameType = Car extends Name ? string : any; // string
// 定义 carNameType 类型的变量 carName
const carName: carNameType = 'Ford';
console.log(carName); // Ford

编译后,将生成以下 JavaScript 代码。

// 定义 carNameType 类型的变量 carName
const carName = 'Ford';
console.log(carName); // Ford 

输出

Ford

泛型条件类型

现在,让我们学习泛型条件类型。在 TypeScript 中,泛型类型类似于函数中的参数。它允许开发者定义条件类型,以便在代码的多个地方使用。它提供了在条件语句中使用不同类型的灵活性。

语法

你可以使用以下语法来使用泛型条件类型。

type ConditionalType<T> = T extends Type1 ? TrueType : FalseType;
  • 在上述语法中,'conditionalType<T>' 具有类型 'T' 参数,'conditionalType' 是类型的名称。

  • 条件 'T extends Type1' 检查类型 'T' 是否扩展 'Type1'。

  • 如果条件评估为 true,则 'TrueType' 将被分配给 'ConditionalType'。否则,将分配 'FalseType'。

示例

在下面的代码中,'IsNumArray<T>' 是一个泛型类型,它将类型 'T' 作为参数。它检查 'T' 的类型是否为数字数组(number[])。如果是,则返回 'number'。否则,返回 'string'。

之后,我们定义了 'num' 和 'str' 变量,并使用 'IsNumArray' 类型与它们一起使用。对于 'num' 变量,我们使用了 'number[]' 参数,对于 'str' 变量,我们使用了 'string[]' 参数。

// 泛型条件类型
type IsNumArray<T> = T extends number[] ? number : string;
const num: IsNumArray<number[]> = 5; // number
const str: IsNumArray<string[]> = '5'; // string
console.log(num);
console.log(str);

编译后,将生成以下 JavaScript 代码。

const num = 5; // number
const str = '5'; // string
console.log(num);
console.log(str);

输出

5
5

条件类型约束

条件类型约束也被称为类型断言或条件类型谓词。它用于对泛型添加约束。泛型是可重用的,但如果您想将它们重用于特定数据类型如 array、number 等,则应为泛型添加约束。

语法

您可以遵循以下语法来使用条件类型约束。

type ConditionalType<T extends T1 | T2> = T extends Type1 ? TrueType : FalseType;

在上述语法中,我们为类型参数 'T' 添加了约束。它接受类型 'T1' 和 'T2' 的值。

示例

在下面的代码中,'ConditionalType' 是一个泛型。它将 number 或 string 类型作为类型参数 'T' 的值。条件类型如果 'T' 的类型是 number,则返回 number;否则,返回 string。

接下来,我们通过传递 number 和 string 作为类型参数,重用了 ConditionalType 类型。

您会注意到,当我们尝试使用 'boolean' 作为类型参数时,会抛出错误。因此,它允许以有限的类型重用此泛型条件类型。

// 定义带有约束的条件类型
type ConditionalType<T extends number | string> = T extends number ? number : string;
let x: ConditionalType<number> = 10;
let y: ConditionalType<string> = 'Hello';
// let z: ConditionalType<boolean> = true; // 错误:类型 'boolean' 不满足约束 'number | string'。
console.log("The value of x is: ", x);
console.log("The value of y is: ", y);

编译后,将生成以下 JavaScript 代码。

let x = 10;
let y = 'Hello';
// let z: ConditionalType<boolean> = true; // 错误:类型 'boolean' 不满足约束 'number | string'。
console.log("The value of x is: ", x);
console.log("The value of y is: ", y);

输出

The value of x is:  10
The value of y is:  Hello

条件类型中的推断

在 TypeScript 中,条件类型中的推断意味着在条件类型定义中推断类型。它允许您创建更灵活的类型转换。

例如,如果您有一个元素数组,并将其与条件类型中的类型 'T' 匹配。然后,如果条件为真,您希望返回数组元素的类型,在这种情况下,推断条件类型非常有用。

语法

您可以使用 'infer' 关键字在条件类型中进行推断。

type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;

在上述语法中,'infer' 关键字用于提取数组元素的类型。

示例

在下面的代码中,我们创建了 'Flatten' 条件类型。我们使用 infer 关键字与类型 'U' 一起。它从具有类型 'U' 的元素数组中提取 'U' 的类型。

对于 'Flatten<boolean>',它将返回 boolean。因此,如果我们尝试将 string 值赋给 'bool1' 变量,会抛出错误。

// 条件类型中的推断
type Flatten<T> = T extends (infer U)[] ? U : T;
let bool: Flatten<boolean[]> = true;
// let bool1: Flatten<boolean> = "s"; // 错误:string 无法赋值给 boolean
console.log(bool);

编译后,将生成以下 JavaScript 代码。

let bool = true;
// let bool1: Flatten<boolean> = "s"; // 错误:string 无法赋值给 boolean
console.log(bool);

输出

true

通过这种方式,您可以在 TypeScript 中使用条件类型。您可以使用泛型,并推断它们,使类型转换更加灵活。