高级 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"}
如您所见,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<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}
这里,我们有另一个例子,它有一个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"]}
泛型类型可以接收多个参数。这里,我们传入两个参数:T
和U
,然后将它们用作属性的类型注释。也就是说,我们现在可以使用接口并提供不同的类型作为参数。
实用程序类型
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"}
如您所见,我们有一个接口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
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.
这里,我们使用了实用程序Readonly
来使属性ReadonlyType
不可重新赋值。也就是说,如果你尝试为这些字段之一赋予新值,则会抛出错误。
除此之外,您还可以readonly
在属性前使用关键字,使其不可重新分配。
interface ReadonlyType {
readonly id: number
name: string
}
挑选
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">'
Pick
与我们已经见过的先前实用程序略有不同。它需要两个参数 -T
是要从中选择元素的类型以及K
要选择的属性。您还可以通过使用竖线 ( |
) 符号分隔来选择多个字段。
忽略
Omit<T, K>
实用程序Omit
与类型相反。它不是选择元素,而是从类型中Pick
删除属性。K
T
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">'
此实用程序与工作方式类似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"
这里,我们有两个类型具有共同的属性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"
正如您在此处看到的,属性firstName
和lastName
可以分配给SecondType
类型,因为它们不存在。通过使用Extract
关键字,我们可以按预期返回这些字段。
记录
Record<K,T>
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 作为变量的键。如果您尝试使用字符串作为属性,则会引发错误。接下来,属性集由包含字段 id、fullName 和 role 的对象employees
给出。EmployeeType
不可空
NonNullable<T>
它允许您从类型中删除null
和。undefined
T
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'.
在这里,我们将类型NonNullableType
作为参数传递给实用程序,该实用程序通过从该类型中排除和来NonNullable
构造新类型。也就是说,如果传递可空值,TypeScript 将抛出错误。null
undefined
顺便说一句,如果你将--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"}
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> = T extends null | undefined ? never : T
此NonNullable
实用程序类型的示例检查类型是否为空,并根据情况进行处理。如您所见,它使用了 JavaScript 三元运算符。
谢谢阅读。
您可以在我的博客上找到其他类似的精彩内容,或者在 Twitter 上关注我以获取通知。
文章来源:https://dev.to/ibrahima92/advanced-typescript-types-cheat-sheet-with-examples-5414