高级 TypeScript 类型速查表(含示例)

2025-05-24

高级 TypeScript 类型速查表(含示例)

TypeScript 是一种类型化语言,允许您指定变量、函数参数、返回值和对象属性的类型。

这里有一个带有示例的高级 TypeScript 类型备忘单。

让我们深入了解

最初发布在我的博客上

交叉口类型

交叉类型是将多个类型合并为一个类型。这意味着您可以将给定的类型 A 与一个或多个类型 B 合并,并返回一个包含所有属性的类型。

type LeftType = {
  id: number
  left: string
}

type RightType = {
  id: number
  right: string
}

type IntersectionType = LeftType & RightType

function showType(args: IntersectionType) {
  console.log(args)
}

showType({ id: 1, left: "test", right: "test" })
// Output: {id: 1, left: "test", right: "test"}
Enter fullscreen mode Exit fullscreen mode

如您所见,IntersectionType结合了两种类型 -LeftTypeRightType并使用&符号来构造交集类型。

联合类型

联合类型允许您在给定变量内拥有不同类型的注释。

type UnionType = string | number

function showType(arg: UnionType) {
  console.log(arg)
}

showType("test")
// Output: test

showType(7)
// Output: 7
Enter fullscreen mode Exit fullscreen mode

该函数showType是联合类型,接受字符串和数字作为参数。

泛型类型

泛型是一种重用给定类型部分内容的方法。它有助于捕获T作为参数传入的类型。

function showType<T>(args: T) {
  console.log(args)
}

showType("test")
// Output: "test"

showType(1)
// Output: 1
Enter fullscreen mode Exit fullscreen mode

要构造泛型类型,需要使用括号并将其T作为参数传递。
在这里,我使用T(名称由您决定),然后showType使用不同的类型注释调用该函数两次,因为它是泛型的——可以重复使用。

interface GenericType<T> {
  id: number
  name: T
}

function showType(args: GenericType<string>) {
  console.log(args)
}

showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}

function showTypeTwo(args: GenericType<number>) {
  console.log(args)
}

showTypeTwo({ id: 1, name: 4 })
// Output: {id: 1, name: 4}
Enter fullscreen mode Exit fullscreen mode

这里,我们有另一个例子,它有一个GenericType接收泛型类型的接口T。由于它是可重用的,我们可以先用字符串,然后用数字来调用它。

interface GenericType<T, U> {
  id: T
  name: U
}

function showType(args: GenericType<number, string>) {
  console.log(args)
}

showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}

function showTypeTwo(args: GenericType<string, string[]>) {
  console.log(args)
}

showTypeTwo({ id: "001", name: ["This", "is", "a", "Test"] })
// Output: {id: "001", name: Array["This", "is", "a", "Test"]}
Enter fullscreen mode Exit fullscreen mode

泛型类型可以接收多个参数。这里,我们传入两个参数:TU,然后将它们用作属性的类型注释。也就是说,我们现在可以使用接口并提供不同的类型作为参数。

实用程序类型

TypeScript 提供了一些便捷的内置工具,方便您轻松操作类型。要使用它们,您需要传入<>要转换的类型。

部分的

  • Partial<T>

Partial 允许你将类型的所有属性设为可选。它会在每个字段旁边T添加一个标记。?

interface PartialType {
  id: number
  firstName: string
  lastName: string
}

function showType(args: Partial<PartialType>) {
  console.log(args)
}

showType({ id: 1 })
// Output: {id: 1}

showType({ firstName: "John", lastName: "Doe" })
// Output: {firstName: "John", lastName: "Doe"}
Enter fullscreen mode Exit fullscreen mode

如您所见,我们有一个接口PartialType,它用作函数接收参数的类型注释showType()。为了使属性成为可选属性,我们必须使用Partial关键字并将类型PartialType作为参数传入。也就是说,现在所有字段都变为可选的了。

必需的

  • Required<T>

与 不同Partial,该Required实用程序使该类型的所有属性都T成为必需的。

interface RequiredType {
  id: number
  firstName?: string
  lastName?: string
}

function showType(args: Required<RequiredType>) {
  console.log(args)
}

showType({ id: 1, firstName: "John", lastName: "Doe" })
// Output: { id: 1, firstName: "John", lastName: "Doe" }

showType({ id: 1 })
// Error: Type '{ id: number: }' is missing the following properties from type 'Required<RequiredType>': firstName, lastName
Enter fullscreen mode Exit fullscreen mode

Required即使我们在使用该实用程序之前先将所有属性设置为可选,该实用程序也会将所有属性设置为必需。如果省略了某个属性,TypeScript 将会抛出错误。

只读

  • Readonly<T>

此实用程序类型将转换该类型的所有属性T,以使它们不能重新分配新值。

interface ReadonlyType {
  id: number
  name: string
}

function showType(args: Readonly<ReadonlyType>) {
  args.id = 4
  console.log(args)
}

showType({ id: 1, name: "Doe" })
// Error: Cannot assign to 'id' because it is a read-only property.
Enter fullscreen mode Exit fullscreen mode

这里,我们使用了实用程序Readonly来使属性ReadonlyType不可重新赋值。也就是说,如果你尝试为这些字段之一赋予新值,则会抛出错误。

除此之外,您还可以readonly在属性前使用关键字,使其不可重新分配。

interface ReadonlyType {
  readonly id: number
  name: string
}
Enter fullscreen mode Exit fullscreen mode

挑选

  • Pick<T, K>

T它允许您通过选择K该类型的一些属性从现有模型创建新类型。

interface PickType {
  id: number
  firstName: string
  lastName: string
}

function showType(args: Pick<PickType, "firstName" | "lastName">) {
  console.log(args)
}

showType({ firstName: "John", lastName: "Doe" })
// Output: {firstName: "John"}

showType({ id: 3 })
// Error: Object literal may only specify known properties, and 'id' does not exist in type 'Pick<PickType, "firstName" | "lastName">'
Enter fullscreen mode Exit fullscreen mode

Pick与我们已经见过的先前实用程序略有不同。它需要两个参数 -T是要从中选择元素的类型以及K要选择的属性。您还可以通过使用竖线 ( |) 符号分隔来选择多个字段。

忽略

  • Omit<T, K>

实用程序Omit与类型相反。它不是选择元素,而是从类型中Pick删除属性KT

interface PickType {
  id: number
  firstName: string
  lastName: string
}

function showType(args: Omit<PickType, "firstName" | "lastName">) {
  console.log(args)
}

showType({ id: 7 })
// Output: {id: 7}

showType({ firstName: "John" })
// Error: Object literal may only specify known properties, and 'firstName' does not exist in type 'Pick<PickType, "id">'
Enter fullscreen mode Exit fullscreen mode

此实用程序与工作方式类似Pick。它需要类型以及从该类型中省略的属性。

提炼

  • Extract<T, U>

Extract允许您通过选取两种不同类型中存在的属性来构造类型。该实用程序将从中提取T所有可赋值的属性U

interface FirstType {
  id: number
  firstName: string
  lastName: string
}

interface SecondType {
  id: number
  address: string
  city: string
}

type ExtractType = Extract<keyof FirstType, keyof SecondType>
// Output: "id"
Enter fullscreen mode Exit fullscreen mode

这里,我们有两个类型具有共同的属性id。因此,通过使用Extract关键字,我们可以返回 字段id,因为它存在于两个接口中。如果您有多个共享字段,该实用程序将提取所有相似的属性。

排除

与 不同Extract,该Exclude实用程序将通过排除已存在于两种不同类型中的属性来构建类型。它会排除T所有可赋值的字段U

interface FirstType {
  id: number
  firstName: string
  lastName: string
}

interface SecondType {
  id: number
  address: string
  city: string
}

type ExcludeType = Exclude<keyof FirstType, keyof SecondType>

// Output; "firstName" | "lastName"
Enter fullscreen mode Exit fullscreen mode

正如您在此处看到的,属性firstNamelastName可以分配给SecondType类型,因为它们不存在。通过使用Extract关键字,我们可以按预期返回这些字段。

记录

  • Record<K,T>

K此实用程序可帮助您构建具有给定类型的一组属性的类型TRecord在将一种类型的属性映射到另一种类型的属性时非常方便。

interface EmployeeType {
  id: number
  fullname: string
  role: string
}

let employees: Record<number, EmployeeType> = {
  0: { id: 1, fullname: "John Doe", role: "Designer" },
  1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
  2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}

// 0: { id: 1, fullname: "John Doe", role: "Designer" },
// 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
// 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }
Enter fullscreen mode Exit fullscreen mode

Record工作原理相对简单。这里,它要求 anumber作为类型,因此我们将 0、1 和 2 作为变量的键。如果您尝试使用字符串作为属性,则会引发错误。接下来,属性集由包含字段 id、fullName 和 role 的对象employees给出。EmployeeType

不可空

  • NonNullable<T>

它允许您从类型中删除nullundefinedT

type NonNullableType = string | number | null | undefined

function showType(args: NonNullable<NonNullableType>) {
  console.log(args)
}

showType("test")
// Output: "test"

showType(1)
// Output: 1

showType(null)
// Error: Argument of type 'null' is not assignable to parameter of type 'string | number'.

showType(undefined)
// Error: Argument of type 'undefined' is not assignable to parameter of type 'string | number'.
Enter fullscreen mode Exit fullscreen mode

在这里,我们将类型NonNullableType作为参数传递给实用程序,该实用程序通过从该类型中排除和来NonNullable构造新类型。也就是说,如果传递可空值,TypeScript 将抛出错误。nullundefined

顺便说一句,如果你将--strictNullChecks标志添加到tsconfig文件,TypeScript 将应用非空性规则。

映射类型

映射类型允许您将现有模型的每个属性转换为新类型。请注意,前面介绍的一些实用类型也是映射类型。

type StringMap<T> = {
  [P in keyof T]: string
}

function showType(arg: StringMap<{ id: number; name: string }>) {
  console.log(arg)
}

showType({ id: 1, name: "Test" })
// Error: Type 'number' is not assignable to type 'string'.

showType({ id: "testId", name: "This is a Test" })
// Output: {id: "testId", name: "This is a Test"}
Enter fullscreen mode Exit fullscreen mode

StringMap<>会将传入的任何类型转换为字符串。也就是说,如果我们在函数中使用它showType(),接收的参数必须是字符串——否则,TypeScript 会抛出错误。

类型保护

类型保护允许你使用运算符检查变量或对象的类型。它是一个条件块typeof,使用instanceof、 或来返回类型in

  • typeof
function showType(x: number | string) {
  if (typeof x === "number") {
    return `The result is ${x + x}`
  }
  throw new Error(`This operation can't be done on a ${typeof x}`)
}

showType("I'm not a number")
// Error: This operation can't be done on a string

showType(7)
// Output: The result is 14
Enter fullscreen mode Exit fullscreen mode

如你所见,我们有一个普通的 JavaScript 条件块,用于检查所接收参数的类型typeof。有了它,你现在可以用这个条件来保护你的类型了。

  • instanceof
class Foo {
  bar() {
    return "Hello World"
  }
}

class Bar {
  baz = "123"
}

function showType(arg: Foo | Bar) {
  if (arg instanceof Foo) {
    console.log(arg.bar())
    return arg.bar()
  }

  throw new Error("The type is not supported")
}

showType(new Foo())
// Output: Hello World

showType(new Bar())
// Error: The type is not supported
Enter fullscreen mode Exit fullscreen mode

与前面的示例一样,这也是一个类型保护,它检查接收到的参数是否是Foo类的一部分,并进行相应的处理。

  • in
interface FirstType {
  x: number
}
interface SecondType {
  y: string
}

function showType(arg: FirstType | SecondType) {
  if ("x" in arg) {
    console.log(`The property ${arg.x} exists`)
    return `The property ${arg.x} exists`
  }
  throw new Error("This type is not expected")
}

showType({ x: 7 })
// Output: The property 7 exists

showType({ y: "ccc" })
// Error: This type is not expected
Enter fullscreen mode Exit fullscreen mode

in运算符允许您检查x作为参数接收的对象上是否存在属性。

条件类型

它测试两种类型并根据测试结果选择其中一种。

type NonNullable<T> = T extends null | undefined ? never : T
Enter fullscreen mode Exit fullscreen mode

NonNullable实用程序类型的示例检查类型是否为空,并根据情况进行处理。如您所见,它使用了 JavaScript 三元运算符。

谢谢阅读。

您可以在我的博客上找到其他类似的精彩内容,或者在 Twitter 上关注我以获取通知。

文章来源:https://dev.to/ibrahima92/advanced-typescript-types-cheat-sheet-with-examples-5414
PREV
如何使用 HTML、CSS 和 JavaScript 从头开始​​构建 PWA?
NEXT
React Router 初学者完整指南(包括 Router Hooks)