最强的高级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<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"]}
泛型类型可以接收多个参数。在这里,我们传入两个参数: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离我更远了,快乐离我更近了