最强的高级TypeScript类型备忘单【含示例】

前端人

共 7870字,需浏览 16分钟

 ·

2021-02-23 14:26

文章来源:Dev

文章地址:dev.to/ibrahima92/advanced-typescript-types-cheat-sheet-with-examples-5414


关注公众号 前端人,回复“加群

添加无广告优质学习群

今天这篇ts文章,绝对的干货满满,绝对的值得收藏,今天鬼哥强烈建议好好看看

交叉点类型

相交类型是一种将多种类型组合为一种类型的方法。这意味着您可以将给定的类型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"}

如您所见,IntersectionType将两种类型组合在一起- LeftType,RightType然后使用&符号构造交点类型。

联合类型

联合类型使您可以在给定变量中使用不同类型的注释。

type UnionType = string | number

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

showType("test")
// Output: test

showType(7)
// Output: 7

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

通用类型

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

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

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

showType(1)
// Output: 1

要构造泛型类型,您需要使用方括号并将其T作为参数传递。

在这里,我使用T(名称由您决定),然后showType使用不同的类型注释两次调用该函数,因为它是通用的-可以重用。

interface GenericType {
  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}

在这里,我们有另一个示例,该示例具有一个GenericType接收通用类型的接口T。由于它是可重用的,因此我们可以先使用字符串,然后使用数字来调用它。

interface GenericType {
  id: T
  name: U
}

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

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

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

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

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

实用程序类型 TypeScript提供了方便的内置实用程序,可帮助轻松地操作类型。要使用它们,您需要传递<>要转换的类型。

部分的

Partial

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

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

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

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

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

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

必需的

Required

不同于Partial,该Required实用程序将提供T所需类型的所有属性。

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

function showType(args: Required{
  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': firstName, lastName

Required即使我们在使用该实用程序之前先将它们设为可选,该实用程序也会提供所有必需的属性。而且,如果省略属性,TypeScript将引发错误。

只读

Readonly

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

interface ReadonlyType {
id: number
name: string
}

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

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

在这里,我们使用该实用程序Readonly来使属性ReadonlyType不能重新分配。也就是说,如果您尝试为这些字段之一赋予新值,则会引发错误。

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

interface ReadonlyType {
readonly id: number
name: string
}

挑选

Pick

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

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

function showType(args: Pick{
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'

Pick与我们已经看到的以前的实用程序有些不同。它需要两个参数-T是您要从中选择元素的类型K,也是要选择的属性。您也可以通过使用pipe(|)符号将它们分开来选择多个字段。

忽略

Omit

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

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

function showType(args: Omit{
  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'

此实用程序类似于Pick工作方式。它期望类型和属性从该类型中省略。

提炼

Extract
Extract允许您通过选择两种不同类型中存在的属性来构造类型。该实用程序将从T可分配给的所有属性中提取U。
interface FirstType {
id: number
firstName: string
lastName: string
}

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

type ExtractType = Extract
// Output: "id"

在这里,我们有两种共同的特性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

// Output; "firstName" | "lastName"

如您所见,属性firstName和lastName可分配给SecondType类型,因为它们在那里不存在。通过使用Extract关键字,我们可以按预期返回这些字段。

记录

Record

该实用程序可帮助您构造K具有给定类型的一组属性的类型T。Record在将一个类型的属性映射到另一个类型的属性时非常方便。

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" }

该方法Record的作品是比较简单的。在这里,它期望anumber作为类型,这就是为什么我们将0、1和2作为employees变量的键的原因。而且,如果您尝试使用字符串作为属性,则会引发错误。接下来,属性集由EmployeeType具有字段id,fullName和role的对象给出。

不可为空

NonNullable

它允许你删除null,并undefined从类型T。

type NonNullableType = string | number | null | undefined

function showType(args: NonNullable{
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'.

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

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

映射类型

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

type StringMap = {
[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"}

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

如您所见,我们有一个普通的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

像前面的示例一样,这也是一个类型防护,它检查接收到的参数是否是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

该in允许你检查属性是否x收为参数的对象上存在与否。

条件类型

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

type NonNullable = T extends null | undefined ? never : T

NonNullable实用程序类型的此示例检查类型是否为null并根据该值进行处理。正如您所注意到的,它使用JavaScript三元运算符。

  • 回复资料包领取我整理的进阶资料包
  • 回复加群,加入前端进阶群
  • console.log("点赞===看===你我都快乐"
  • Bug离我更远了,快乐离我更近了

浏览 37
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报