What are the benefits of using TypeScript in web development?

2026-04-27 18:271阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1869个文字,预计阅读时间需要8分钟。

What are the benefits of using TypeScript in web development?

目录 + TypeScript 的条件类型使用方式 + 条件类型和 keyof 组合 + 在条件返回中使用 T + 在类型输出中使用 T + 联合类型时的结合 + 使用条件类型推断类型 + 总结 + TypeScript 的条件类型使用方式 + 我们可以使用它...

目录
  • TypeScript 的条件类型使用方式
  • 条件类型和 keyof 组合
  • 在条件返回中使用 T
  • 在类型输出中使用 T 时的联合类型
  • 使用条件类型推断类型
  • 总结

TypeScript 的条件类型使用方式

我们可以使用 TypeScript 中的条件类型来根据逻辑定义某些类型,就像是在编写代码那样。

它采用的语法和我们在 JavaScript 中熟悉的三元运算符很像:condition ? ifConditionTrue : ifConditionFalse。

我们来看看他是怎么工作的。

假设我们有一个值,这个值可以表示用户的出生日期或者年龄。

  • 如果是出生日期,那他的类型应该是 string。
  • 如果是年龄,那他的类型是 number。

我们来定义这三种类型。

type Dob = string; type Age = number; type UserAgeInformation<T> = T extends number ? number : string;

Dob 和 Age 不需要多解释,我们来解释一下 UserAgeInformation。

它接受一个泛型,可以是任何类型。如果 T extends number 为 true,就意味着传入的类型是 number 类型,我们就把 UserAgeInformation 设置为 number 类型。否则的话就设置为 string 类型。

我们在使用的时候可以这样:

let userAge:UserAgeInformation<Age> = 100; let userDob:UserAgeInformation<Dob> = '12/12/1945';

条件类型和 keyof 组合

除了上面介绍的用法,我们还可以通过检查是否扩展了一个对象来更进一步。比如,假设我们的客户有两种类型:Horse 和 User。

两种类型的客户都有 age、name 两个字段。

  • User 类型的客户还有一个 address 字段,它表示了详细的地址。
  • Horse 类型的客户有 location 两个字段,它只是表示一个大概的位置。

我们来定义这几种类型:

type User = { age: number, name: string, address: string } type Horse = { age: number, name: string } type UserAddress = { addressLine1: string, city: string, country: string, } type HorseAddress = { location: 'farm' | 'savanna' | 'field' | 'other' }

在未来,我们还可能会有其他类型的客户,所以我们可以通过检查 T 是否具有 address 属性,如果有,我们使用 UserAddress 类型,否则使用 HorseAddress 类型。

type AddressComponents<T> = T extends { address: string } ? UserAddress : HorseAddress let userAddress:AddressComponents<User> = { addressLine1: "123 Fake Street", city: "Boston", country: "USA" } let horseAddress:AddressComponents<Horse> = { location: 'farm' }

T extends { address: string } 的含义是检查 T 是否具有 address 属性。

在条件返回中使用 T

在三元表达式的条件返回中,我们也可以使用 T。

比如下面的例子:

type User = { age: number, name: string, address: string } type Horse = { age: number, name: string } type UserType<T> = T extends { address: string } ? T : Horse let myUser: UserType<User> = { age: 104, name: "John Doe", address: "123 Fake Street" }

T 被定义为 User,当我们调用 UserType 时,myUser 的类型就是 User,并且需要具有这种类型中所定义的字段。

在类型输出中使用 T 时的联合类型

如果我们在这里传递一个联合类型:

type UserType<T> = T extends { address: string } ? T : string let myUser: UserType<User | Horse> = { age: 104, name: "John Doe", address: "123 Fake Street" }

myUser 的类型会变成是 User|string,因为 User 通过了条件检测,但是 Horse 没有通过,所以它的类型是字符串。

如果我们以某种方式修改 T,比如把它设置为数组。所有 T 的值都会被单独修改。

type User = { age?: number, name: string, address?: string } type Horse = { age?: number, name: string } // 如果 T 包含类型是 string 的 name 属性,就会返回 T[] type UserType<T> = T extends { name: string } ? T[] : never; // myUser 的类型是 User[]|Horse[],因为 User 和 Horse 都具有 name 属性 let myUser:UserType<User | Horse> = [{ name: "John" }, { name: "Horse" }]

在这里我们已经简化了 User 和 Horse,它们只留下了必须需要的 name 字段。在条件类型中,两种类型都包含了 name。

所以两者都会返回 true,并且返回的类型是 T[],由于两者都返回 true,所以 myUser 的类型是 User[]|Horse[],所以我们可以简单地提供一个包含 name 属性的对象数组。

这种行为通常很好,但是在某些情况下,我们希望返回一个数组。

在这种情况下,如果我们想避免这样分布类型,可以在 周围添加 { name: string }。

type User = { age?: number, name: string, address?: string } type Horse = { age?: number, name: string } // 我们避免分布类型,因为 T 和 { name: string} 都在方括号中 type UserType<T> = [T] extends [{ name: string }] ? T[] : never; // 这样现在的类型不同了,它是 (User|Horse)[] let myUser:UserType<User | Horse> = [{ name: "John" }, { name: "Horse" }]

通过使用方括号,我们的类型已经转为 (User|Horse)[],而不是 User[]|Horse[]。

这在某些特殊的场景中很有用。但是条件类型会增加复杂性,不可以滥用。

使用条件类型推断类型

我们也可以在使用条件时使用 infer 关键字。

假设我们有两种类型,一种用于数字数组,另一种用于字符串数组。

在这个例子中,infer 将会推断数组中每个项目的类型,并返回正确的类型:

type StringArray = string[] type NumberArray = number[] type MixedArray = number[] | string[] type ArrayType<T> = T extends Array<infer Item> ? Item: never // 因为 NumberArray 中项目的类型是 number,所以 myItem1 是 number 类型 let myItem1: ArrayType<NumberArray> = 45 // 因为 StringArray 中项目的类型是 string,所以 myItem2 是 string 类型 let myItem2: ArrayType<StringArray> = 'string' // 因为 MixedArray 中项目的类型是 number|string,所以 myItem3 是 number|string 类型 let myItem3: ArrayType<MixedArray> = 'string'

我们在条件类型中定义了一个新的参数 Item,它是 extends Array 中的子项 T。

但是我们必须传入数组,它才会有效,因为我们使用的是 Array。

如果 T 不是数组,那么 ArrayType 的类型将会是 never。

总结

如果你刚接触到 TypeScript 的条件类型,你可能会觉得很疑惑。但是它解决了某些特定情况下编写类型比较复杂的一种解决方式。

What are the benefits of using TypeScript in web development?

如果你在某个项目中看到它,或者简化你想你的项目代码,它或许很有用。

以上就是TypeScript 的条件类型使用详解 的详细内容,更多关于TypeScript 条件类型的资料请关注易盾网络其它相关文章!

本文共计1869个文字,预计阅读时间需要8分钟。

What are the benefits of using TypeScript in web development?

目录 + TypeScript 的条件类型使用方式 + 条件类型和 keyof 组合 + 在条件返回中使用 T + 在类型输出中使用 T + 联合类型时的结合 + 使用条件类型推断类型 + 总结 + TypeScript 的条件类型使用方式 + 我们可以使用它...

目录
  • TypeScript 的条件类型使用方式
  • 条件类型和 keyof 组合
  • 在条件返回中使用 T
  • 在类型输出中使用 T 时的联合类型
  • 使用条件类型推断类型
  • 总结

TypeScript 的条件类型使用方式

我们可以使用 TypeScript 中的条件类型来根据逻辑定义某些类型,就像是在编写代码那样。

它采用的语法和我们在 JavaScript 中熟悉的三元运算符很像:condition ? ifConditionTrue : ifConditionFalse。

我们来看看他是怎么工作的。

假设我们有一个值,这个值可以表示用户的出生日期或者年龄。

  • 如果是出生日期,那他的类型应该是 string。
  • 如果是年龄,那他的类型是 number。

我们来定义这三种类型。

type Dob = string; type Age = number; type UserAgeInformation<T> = T extends number ? number : string;

Dob 和 Age 不需要多解释,我们来解释一下 UserAgeInformation。

它接受一个泛型,可以是任何类型。如果 T extends number 为 true,就意味着传入的类型是 number 类型,我们就把 UserAgeInformation 设置为 number 类型。否则的话就设置为 string 类型。

我们在使用的时候可以这样:

let userAge:UserAgeInformation<Age> = 100; let userDob:UserAgeInformation<Dob> = '12/12/1945';

条件类型和 keyof 组合

除了上面介绍的用法,我们还可以通过检查是否扩展了一个对象来更进一步。比如,假设我们的客户有两种类型:Horse 和 User。

两种类型的客户都有 age、name 两个字段。

  • User 类型的客户还有一个 address 字段,它表示了详细的地址。
  • Horse 类型的客户有 location 两个字段,它只是表示一个大概的位置。

我们来定义这几种类型:

type User = { age: number, name: string, address: string } type Horse = { age: number, name: string } type UserAddress = { addressLine1: string, city: string, country: string, } type HorseAddress = { location: 'farm' | 'savanna' | 'field' | 'other' }

在未来,我们还可能会有其他类型的客户,所以我们可以通过检查 T 是否具有 address 属性,如果有,我们使用 UserAddress 类型,否则使用 HorseAddress 类型。

type AddressComponents<T> = T extends { address: string } ? UserAddress : HorseAddress let userAddress:AddressComponents<User> = { addressLine1: "123 Fake Street", city: "Boston", country: "USA" } let horseAddress:AddressComponents<Horse> = { location: 'farm' }

T extends { address: string } 的含义是检查 T 是否具有 address 属性。

在条件返回中使用 T

在三元表达式的条件返回中,我们也可以使用 T。

比如下面的例子:

type User = { age: number, name: string, address: string } type Horse = { age: number, name: string } type UserType<T> = T extends { address: string } ? T : Horse let myUser: UserType<User> = { age: 104, name: "John Doe", address: "123 Fake Street" }

T 被定义为 User,当我们调用 UserType 时,myUser 的类型就是 User,并且需要具有这种类型中所定义的字段。

在类型输出中使用 T 时的联合类型

如果我们在这里传递一个联合类型:

type UserType<T> = T extends { address: string } ? T : string let myUser: UserType<User | Horse> = { age: 104, name: "John Doe", address: "123 Fake Street" }

myUser 的类型会变成是 User|string,因为 User 通过了条件检测,但是 Horse 没有通过,所以它的类型是字符串。

如果我们以某种方式修改 T,比如把它设置为数组。所有 T 的值都会被单独修改。

type User = { age?: number, name: string, address?: string } type Horse = { age?: number, name: string } // 如果 T 包含类型是 string 的 name 属性,就会返回 T[] type UserType<T> = T extends { name: string } ? T[] : never; // myUser 的类型是 User[]|Horse[],因为 User 和 Horse 都具有 name 属性 let myUser:UserType<User | Horse> = [{ name: "John" }, { name: "Horse" }]

在这里我们已经简化了 User 和 Horse,它们只留下了必须需要的 name 字段。在条件类型中,两种类型都包含了 name。

所以两者都会返回 true,并且返回的类型是 T[],由于两者都返回 true,所以 myUser 的类型是 User[]|Horse[],所以我们可以简单地提供一个包含 name 属性的对象数组。

这种行为通常很好,但是在某些情况下,我们希望返回一个数组。

在这种情况下,如果我们想避免这样分布类型,可以在 周围添加 { name: string }。

type User = { age?: number, name: string, address?: string } type Horse = { age?: number, name: string } // 我们避免分布类型,因为 T 和 { name: string} 都在方括号中 type UserType<T> = [T] extends [{ name: string }] ? T[] : never; // 这样现在的类型不同了,它是 (User|Horse)[] let myUser:UserType<User | Horse> = [{ name: "John" }, { name: "Horse" }]

通过使用方括号,我们的类型已经转为 (User|Horse)[],而不是 User[]|Horse[]。

这在某些特殊的场景中很有用。但是条件类型会增加复杂性,不可以滥用。

使用条件类型推断类型

我们也可以在使用条件时使用 infer 关键字。

假设我们有两种类型,一种用于数字数组,另一种用于字符串数组。

在这个例子中,infer 将会推断数组中每个项目的类型,并返回正确的类型:

type StringArray = string[] type NumberArray = number[] type MixedArray = number[] | string[] type ArrayType<T> = T extends Array<infer Item> ? Item: never // 因为 NumberArray 中项目的类型是 number,所以 myItem1 是 number 类型 let myItem1: ArrayType<NumberArray> = 45 // 因为 StringArray 中项目的类型是 string,所以 myItem2 是 string 类型 let myItem2: ArrayType<StringArray> = 'string' // 因为 MixedArray 中项目的类型是 number|string,所以 myItem3 是 number|string 类型 let myItem3: ArrayType<MixedArray> = 'string'

我们在条件类型中定义了一个新的参数 Item,它是 extends Array 中的子项 T。

但是我们必须传入数组,它才会有效,因为我们使用的是 Array。

如果 T 不是数组,那么 ArrayType 的类型将会是 never。

总结

如果你刚接触到 TypeScript 的条件类型,你可能会觉得很疑惑。但是它解决了某些特定情况下编写类型比较复杂的一种解决方式。

What are the benefits of using TypeScript in web development?

如果你在某个项目中看到它,或者简化你想你的项目代码,它或许很有用。

以上就是TypeScript 的条件类型使用详解 的详细内容,更多关于TypeScript 条件类型的资料请关注易盾网络其它相关文章!