TypeScript is a typed language that allows you to specify the type of variables, function parameters, returned values, and object properties.
TypeScript是一种类型化的语言,允许您指定变量的类型,函数参数,返回的值和对象属性。
Here an advanced TypeScript Types cheat sheet with examples.
这里是一个带有示例的高级TypeScript Types备忘单。
Let's dive in.
让我们潜入。
Intersection Types
交叉点类型
Union Types
联合类型
Generic Types
通用类型
Utility Types
实用程序类型
Partial
部分的
Required
需要
Readonly
只读
Pick
挑
Omit
忽略
Extract
提取
Exclude
排除
Record
记录
NonNullable
不可为空
Mapped Types
映射类型
Type Guards
类型防护
Conditional Types
条件类型
An intersection type is a way of combining multiple types into one. This means that you can merge a given type A with a type B or more and get back a single type with all properties.
相交类型是一种将多种类型组合为一种类型的方法。 这意味着您可以将给定的类型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"}
As you can see, IntersectionType
combines two types - LeftType
and RightType
and uses the &
sign to construct the intersection type.
如您所见, IntersectionType
组合了两种类型LeftType
和RightType
并使用&
符号构造相交类型。
Union types allow you to have different types annotation within a given variable.
联合类型使您可以在给定变量中使用不同类型的注释。
type UnionType = string | number
function showType(arg: UnionType) {
console.log(arg)
}
showType("test")
// Output: test
showType(7)
// Output: 7
The function showType
is a union type that accepts both strings and numbers as a parameter.
函数showType
是一个联合类型,它接受字符串和数字作为参数。
A generic type is a way of reusing part of a given type. It helps to capture the type T
passed in as a parameter.
泛型类型是重用给定类型的一部分的一种方式。 它有助于捕获作为参数传入的类型T
function showType(args: T) {
console.log(args)
}
showType("test")
// Output: "test"
showType(1)
// Output: 1
To construct a generic type, you need to use the brackets and pass T
as a parameter.Here, I use T
(the name is up to you) and then, call the function showType
twice with different type annotations because it's generic - it can be reused.
要构造一个泛型类型,需要使用方括号并将T
作为参数传递。在这里,我使用T
(名称由您决定),然后使用不同的类型注释两次调用showType
函数,因为它是泛型的-它可以被重用。
interface GenericType {
id: number
name: T
}
function showType(args: GenericType) {
console.log(args)
}
showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}
function showTypeTwo(args: GenericType) {
console.log(args)
}
showTypeTwo({ id: 1, name: 4 })
// Output: {id: 1, name: 4}
Here, we have another example that has an interface GenericType
which receives a generic type T
. And since it's reusable, we can call it first with a string and then a number.
在这里,我们有另一个示例,该示例具有一个接口GenericType
,该接口接收通用类型T
由于它是可重用的,因此我们可以先使用字符串然后使用数字来调用它。
interface GenericType {
id: T
name: U
}
function showType(args: GenericType) {
console.log(args)
}
showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}
function showTypeTwo(args: GenericType) {
console.log(args)
}
showTypeTwo({ id: "001", name: ["This", "is", "a", "Test"] })
// Output: {id: "001", name: Array["This", "is", "a", "Test"]}
A generic type can receive several arguments. Here, we pass in two parameters: T
and U
, and then use them as type annotations for the properties. That said, we can now use the interface and provide different types as arguments.
泛型类型可以接收多个参数。 在这里,我们传入两个参数: T
和U
,然后将它们用作属性的类型注释。 也就是说,我们现在可以使用该接口并提供不同的类型作为参数。
TypeScript provides handy built-in utilities that help to manipulate types easily. To use them, you need to pass into the <>
the type you want to transform.
TypeScript提供了方便的内置实用程序,可帮助轻松地操作类型。 要使用它们,您需要将要转换的类型传递给<>
。
Partial
Partial
Partial allows you to make all properties of the type T
optional. It will add a ?
mark next to every field.
部分允许您将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"}
As you can see, we have an interface PartialType
which is used as type annotation for the parameters received by the function showType()
. And to make the properties optional, we have to use the Partial
keyword and pass in the type PartialType
as an argument. That said, now all fields become optional.
如您所见,我们有一个PartialType
接口,该接口用作函数showType()
接收的参数的类型注释。 为了使属性成为可选属性,我们必须使用Partial
关键字并将PartialType
类型作为参数传递。 也就是说,现在所有字段都变为可选。
Required
Required
Unlike Partial
, the Required
utility makes all properties of the type T
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
The Required
utility will make all properties required even if we make them optional first before using the utility. And if a property is omitted, TypeScript will throw an error.
即使我们在使用实用程序之前先将它们设为可选, Required
实用程序也会使所有必需属性成为必需。 而且,如果省略属性,TypeScript将引发错误。
Readonly
Readonly
This utility type will transform all properties of the type T
in order to make them not reassignable with a new value.
此实用程序类型将转换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.
Here, we use the utility Readonly
to make the properties of ReadonlyType
not reassignable. That said, if you try to give a new value to one of these fields, an error will be thrown.
在这里,我们使用该工具Readonly
做出的性质ReadonlyType
不重新分配。 也就是说,如果您尝试为这些字段之一赋予新值,则会引发错误。
Besides that, you can also use the keyword readonly
in front of a property to make it not reassignable.
除此之外,还可以在属性前面使用关键字readonly
使其无法重新分配。
interface ReadonlyType {
readonly id: number
name: string
}
Pick
Pick
It allows you to create a new type from an existing model T
by selecting some properties K
of that type.
它允许您通过选择某种类型的属性K
从现有模型T
创建新类型。
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
is a bit different from the previous utilities we have already seen. It expects two parameters - T
is the type you want to pick elements from and K
is the property you want to select. You can also pick multiple fields by separating them with a pipe(|
) symbol.
Pick
与我们已经看到的以前的实用程序有些不同。 它需要两个参数T
是要从中选择元素的类型, K
是要选择的属性。 您也可以通过使用竖线( |
)符号将它们分开来选择多个字段。
Omit
Omit
The Omit
utility is the opposite of the Pick
type. And instead of selecting elements, it will remove K
properties from the type T
.
Omit
实用程序与Pick
类型相反。 而不是选择元素,它将从类型T
删除K
属性。
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'
This utility is similar to the way Pick
works. It expects the type and the properties to omit from that type.
此实用程序类似于“ Pick
工作方式。 它期望类型和属性从该类型中省略。
Extract
Extract
Extract
allows you to construct a type by picking properties that are present in two different types. The utility will extract from T
all properties that are assignable to U
.
Extract
允许您通过选择两种不同类型中存在的属性来构造类型。 该实用程序将从T
提取所有可分配给U
属性。
interface FirstType {
id: number
firstName: string
lastName: string
}
interface SecondType {
id: number
address: string
city: string
}
type ExtractType = Extract
// Output: "id"
Here, we have two types that have in common the property id
. And hence by using the Extract
keyword, we get back the field id
since it's present in both interfaces. And if you have more than one shared field, the utility will extract all similar properties.
在这里,我们有两种共同的属性id
。 因此,通过使用Extract
关键字,由于两个接口中都存在字段id
,因此我们可以获取它。 并且,如果您有多个共享字段,该实用程序将提取所有相似的属性。
Unlike Extract
, the Exclude
utility will construct a type by excluding properties that are already present in two different types. It excludes from T
all fields that are assignable to U
.
与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"
As you can see here, the properties firstName
and lastName
are assignable to the SecondType
type since they are not present there. And by using the Extract
keyword, we get back these fields as expected.
如您在此处看到的,属性firstName
和lastName
可分配给SecondType
类型,因为它们在那里不存在。 通过使用Extract
关键字,我们可以按预期返回这些字段。
Record
Record
This utility helps you to construct a type with a set of properties K
of a given type T
. Record
is really handy when it comes to mapping the properties of a type to another one.
该实用程序可帮助您构造具有给定类型T
一组属性K
的类型。 在将一种类型的属性映射到另一种类型的属性时, Record
确实很方便。
interface EmployeeType {
id: number
fullname: string
role: string
}
let employees: Record = {
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" }
The way Record
works is relatively simple. Here, it expects a number
as a type which is why we have 0, 1, and 2 as keys for the employees
variable. And if you try to use a string as a property, an error will be thrown. Next, the set of properties is given by EmployeeType
hence the object with the fields id, fullName, and role.
Record
工作方式相对简单。 在这里,它期望一个number
作为类型,这就是为什么我们将0、1和2作为employees
变量的键的原因。 并且,如果您尝试使用字符串作为属性,则会引发错误。 接下来,属性集由EmployeeType
给出,因此具有ID,fullName和role字段的对象。
NonNullable
NonNullable
It allows you to remove null
and undefined
from the type T
.
它允许您从类型T
删除null
和undefined
。
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'.
Here, we pass the type NonNullableType
as an argument to the NonNullable
utility which constructs a new type by excluding null
and undefined
from that type. That said, if you pass a nullable value, TypeScript will throw an error.
在这里,我们将类型NonNullableType
作为参数传递给NonNullable
实用程序,该实用程序通过从该类型中排除null
和undefined
来构造新类型。 也就是说,如果您传递可为空的值,TypeScript将引发错误。
By the way, if you add the --strictNullChecks
flag to the tsconfig
file, TypeScript will apply non-nullability rules.
顺便说一句,如果将--strictNullChecks
标志添加到tsconfig
文件,TypeScript将应用非空性规则。
Mapped types allow you to take an existing model and transform each of its properties into a new type. Note that some utility types covered earlier are also mapped types.
映射类型允许您采用现有模型并将其每个属性转换为新类型。 请注意,前面介绍的某些实用程序类型也是映射类型。
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<>
will transform whatever types that passed in into a string. That said, if we use it in the function showType()
, the parameters received must be a string - otherwise, an error will be thrown by TypeScript.
StringMap<>
会将传入的任何类型转换为字符串。 就是说,如果我们在函数showType()
使用它,则接收到的参数必须是字符串-否则,TypeScript将引发错误。
Type Guards allow you to check the type of a variable or an object with an operator. It's a conditional block that returns a type using typeof
, instanceof
, or in
.
类型保护使您可以使用运算符检查变量或对象的类型。 这是一个条件块,它使用typeof
, instanceof
或in
返回类型。
typeof
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
As you can see, we have a normal JavaScript conditional block that checks the type of the argument received with typeof
. With that in place, you can now guard your type with this condition.
如您所见,我们有一个普通JavaScript条件块,它检查通过typeof
接收到的参数的类型。 有了这个,您现在可以在这种情况下保护您的类型。
instanceof
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
Like the previous example, this one is also a type guard that checks if the parameter received is part of the Foo
class or not and handles it consequently.
像前面的示例一样,这也是一个类型防护,它检查接收到的参数是否是Foo
类的一部分,并对其进行处理。
in
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
The in
operator allows you to check whether a property x
exists or not on the object received as a parameter.
使用in
运算符可以检查作为参数接收的对象上是否存在属性x
。
Conditional types test two types and select one of them depending on the outcome of that test.
条件类型测试两种类型,并根据该测试的结果选择其中一种。
type NonNullable = T extends null | undefined ? never : T
This example of the NonNullable
utility type checks if the type is null or not and handle it depending on that. And as you can note, it uses the JavaScript ternary operator.
NonNullable
实用程序类型的此示例检查类型是否为null,并根据该类型进行处理。 正如您所注意到的,它使用JavaScript三元运算符。
Thanks for reading.
谢谢阅读。
You can find other great content like this on my blog or follow me on Twitter to get notified.
您可以在我的博客上找到类似的其他精彩内容,或者在Twitter上关注我以获取通知。
翻译自: https://www.freecodecamp.org/news/advanced-typescript-types-cheat-sheet-with-examples/