@@ -8,11 +8,11 @@ oneline: "The language primitives."
8
8
在本章中,我们将介绍一些在 JavaScript 代码中最常见的值的类型,并说明在 TypeScript 中描述这些类型相应的方法。
9
9
这不是一个详尽的列表,后续章节将描述命名和使用其他类型的更多方法。
10
10
11
- 类型还可以出现在许多地方 ,而不仅仅是类型注释。
11
+ 类型还可以出现在许多 _ 地方 _ ,而不仅仅是类型注释。
12
12
在我们了解类型本身的同时,我们还将了解在哪些地方可以引用这些类型来形成新的结构。
13
13
14
14
我们将首先回顾一下你在编写 JavaScript 或 TypeScript 代码时可能遇到的最基本和最常见的类型。
15
- 这些核心构建块会稍后会形成更复杂的类型 。
15
+ 这些核心构建块稍后会形成更复杂的类型 。
16
16
17
17
## 基本类型:` string ` ,` number ` ,和 ` boolean `
18
18
@@ -169,95 +169,95 @@ names.forEach((s) => {
169
169
与推理规则类似,您不需要明确了解这是如何发生的,但了解它确实发生可以帮助您注意到何时不需要类型注释。
170
170
稍后,我们将看到更多示例,说明值出现的上下文如何影响其类型。
171
171
172
- ## Object Types
172
+ ## Object Types (对象类型)
173
173
174
- Apart from primitives, the most common sort of type you'll encounter is an _ object type _ .
175
- This refers to any JavaScript value with properties, which is almost all of them!
176
- To define an object type, we simply list its properties and their types.
174
+ 除了基本类型之外,您遇到的最常见的类型是 _ 对象类型 _ 。
175
+ 这是指几乎所有具有任何属性的 JavaScript 值!
176
+ 要定义对象类型,我们只需列出其属性及其类型。
177
177
178
- For example, here's a function that takes a point-like object:
178
+ 例如,这是一个采用点状对象的函数:
179
179
180
180
``` ts twoslash
181
- // The parameter's type annotation is an object type
181
+ // 参数的类型注解是对象类型
182
182
function printCoord(pt : { x: number ; y: number }) {
183
183
// ^^^^^^^^^^^^^^^^^^^^^^^^
184
- console .log (" The coordinate's x value is " + pt .x );
185
- console .log (" The coordinate's y value is " + pt .y );
184
+ console .log (" x坐标的值为 " + pt .x );
185
+ console .log (" y坐标的值为 " + pt .y );
186
186
}
187
187
printCoord ({ x: 3 , y: 7 });
188
188
```
189
189
190
- Here, we annotated the parameter with a type with two properties - ` x ` and ` y ` - which are both of type ` number ` .
191
- You can use ` , ` or ` ; ` to separate the properties, and the last separator is optional either way.
190
+ 在这里,我们使用具有两个属性( ` x ` 和 ` y ` )的类型来注释该参数,这两个属性都是 ` number ` 类型。
191
+ 您可以使用 ` "," ` 或 ` ";" ` 来分隔属性,并且最后一个分隔符是可选的。
192
192
193
- The type part of each property is also optional.
194
- If you don't specify a type, it will be assumed to be ` any ` .
193
+ 每个属性的类型部分也是可选的。
194
+ 如果您未指定类型,则将假定为 ` any ` 。
195
195
196
- ### Optional Properties
196
+ ### Optional Properties (可选属性)
197
197
198
- Object types can also specify that some or all of their properties are _ optional _ .
199
- To do this, add a ` ? ` after the property name:
198
+ 对象类型还可以指定其部分或全部属性是 _ 可选 _ 。
199
+ 要这样做,请在属性名称后添加 ` "?" ` :
200
200
201
201
``` ts twoslash
202
202
function printName(obj : { first: string ; last? : string }) {
203
203
// ...
204
204
}
205
- // Both OK
205
+ // 两种都可以
206
206
printName ({ first: " Bob" });
207
207
printName ({ first: " Alice" , last: " Alisson" });
208
208
```
209
209
210
- In JavaScript, if you access a property that doesn't exist, you'll get the value ` undefined ` rather than a runtime error.
211
- Because of this, when you _ read _ from an optional property, you'll have to check for ` undefined ` before using it.
210
+ 在 JavaScript 中,如果访问不存在的属性,您将得到值是 ` undefined ` 而不是运行时错误。
211
+ 因此,当您从可选属性读取时,您必须在使用它之前检查 ` undefined ` 。
212
212
213
213
``` ts twoslash
214
214
// @errors: 2532
215
215
function printName(obj : { first: string ; last? : string }) {
216
- // Error - might crash if ' obj.last' wasn't provided!
216
+ // 错误 - 如果未提供“ obj.last”,可能会意外错误。
217
217
console .log (obj .last .toUpperCase ());
218
218
if (obj .last !== undefined ) {
219
- // OK
219
+ // 正确
220
220
console .log (obj .last .toUpperCase ());
221
221
}
222
222
223
- // A safe alternative using modern JavaScript syntax:
223
+ // 使用 JavaScript 最新语法的安全替代方案:
224
224
console .log (obj .last ?.toUpperCase ());
225
225
}
226
226
```
227
227
228
- ## Union Types
228
+ ## Union Types (联合类型)
229
229
230
- TypeScript's type system allows you to build new types out of existing ones using a large variety of operators.
231
- Now that we know how to write a few types, it's time to start _ combining _ them in interesting ways.
230
+ TypeScript 的类型系统允许您使用多种运算符从现有类型构建新类型。
231
+ 现在我们知道如何编写一些类型,是时候开始以有趣的方式 _ 组合 _ 它们了。
232
232
233
- ### Defining a Union Type
233
+ ### Defining a Union Type (定义联合类型)
234
234
235
- The first way to combine types you might see is a _ union _ type.
236
- A union type is a type formed from two or more other types, representing values that may be _ any one _ of those types.
237
- We refer to each of these types as the union's _ members _ .
235
+ 您可能看到的第一种组合类型的方法是 _ 联合 _ 类型。
236
+ 联合类型是由两个或多个其他类型形成的类型,表示可以是这些类型中的 _ 任何一种 _ 类型的值。
237
+ 我们将这些类型中的每一种称为联合的 _ 成员 _ 。
238
238
239
- Let's write a function that can operate on strings or numbers:
239
+ 让我们编写一个可以对字符串或数字进行操作的函数:
240
240
241
241
``` ts twoslash
242
242
// @errors: 2345
243
243
function printId(id : number | string ) {
244
244
console .log (" Your ID is: " + id );
245
245
}
246
- // OK
246
+ // 正确
247
247
printId (101 );
248
- // OK
248
+ // 正确
249
249
printId (" 202" );
250
- // Error
250
+ // 错误
251
251
printId ({ myID: 22342 });
252
252
```
253
253
254
- ### Working with Union Types
254
+ ### Working with Union Types (使用联合类型)
255
255
256
- It's easy to _ provide _ a value matching a union type - simply provide a type matching any of the union's members.
257
- If you _ have _ a value of a union type, how do you work with it?
256
+ _ 提供 _ 与联合类型匹配的值很容易 - 只需提供与任何联合成员匹配的类型即可。
257
+ 如果您 _ 有 _ 联合类型的值,您如何使用它?
258
258
259
- TypeScript will only allow you to do things with the union if that thing is valid for _ every _ member of the union.
260
- For example, if you have the union ` string | number ` , you can't use methods that are only available on ` string ` :
259
+ TypeScript 仅允许对联合体的 _ 每个 _ 成员都有效的操作。
260
+ 例如,如果您有联合类型 ` string | number ` ,您不能使用仅适用于 ` string ` 的方法:
261
261
262
262
``` ts twoslash
263
263
// @errors: 2339
@@ -266,62 +266,62 @@ function printId(id: number | string) {
266
266
}
267
267
```
268
268
269
- The solution is to _ narrow _ the union with code, the same as you would in JavaScript without type annotations.
270
- _ Narrowing _ occurs when TypeScript can deduce a more specific type for a value based on the structure of the code.
269
+ 解决方案是 _ 缩小 _ 代码的联合范围,就像在没有类型注释的 JavaScript 中一样。
270
+ 当 TypeScript 可以根据代码结构推断出更具体的值类型时,就会发生 _ 缩小 _ 范围。
271
271
272
- For example, TypeScript knows that only a ` string ` value will have a ` typeof ` value ` "string" ` :
272
+ 例如, TypeScript 知道只有 ` string ` 类型的值才会 ` typeof ` 值为 ` "string" ` :
273
273
274
274
``` ts twoslash
275
275
function printId(id : number | string ) {
276
276
if (typeof id === " string" ) {
277
- // In this branch, id is of type ' string'
277
+ // 在此分支中, id 的类型为“ string”
278
278
console .log (id .toUpperCase ());
279
279
} else {
280
- // Here, id is of type ' number'
280
+ // 这里, id 的类型是“ number”
281
281
console .log (id );
282
282
}
283
283
}
284
284
```
285
285
286
- Another example is to use a function like ` Array.isArray ` :
286
+ 另一个例子是使用像 ` Array.isArray ` 这样的函数:
287
287
288
288
``` ts twoslash
289
289
function welcomePeople(x : string [] | string ) {
290
290
if (Array .isArray (x )) {
291
- // Here: 'x' is ' string[]'
291
+ // 这里:“x”是“ string[]”
292
292
console .log (" Hello, " + x .join (" and " ));
293
293
} else {
294
- // Here: 'x' is ' string'
294
+ // 这里:“x”是“ string”
295
295
console .log (" Welcome lone traveler " + x );
296
296
}
297
297
}
298
298
```
299
299
300
- Notice that in the ` else ` branch, we don't need to do anything special - if ` x ` wasn't a ` string[] ` , then it must have been a ` string ` .
300
+ 请注意,在 ` else ` 分支中,我们不需要做任何特殊的事情 - 如果 ` x ` 不是 ` string[] ` ,那么它一定是 ` string ` 。
301
301
302
- Sometimes you'll have a union where all the members have something in common.
303
- For example, both arrays and strings have a ` slice ` method.
304
- If every member in a union has a property in common, you can use that property without narrowing:
302
+ 有时,您会建立一个联合,其中所有成员都有一些共同点。
303
+ 例如,数组和字符串都有一个 ` slice ` 方法。
304
+ 如果联合中的每个成员都有一个共同的属性,则可以使用该属性而无需缩小范围:
305
305
306
306
``` ts twoslash
307
- // Return type is inferred as number[] | string
307
+ // 返回类型被推断为 number[] | string
308
308
function getFirstThree(x : number [] | string ) {
309
309
return x .slice (0 , 3 );
310
310
}
311
311
```
312
312
313
- > It might be confusing that a _ union _ of types appears to have the _ intersection _ of those types' properties.
314
- > This is not an accident - the name _ union _ comes from type theory.
315
- > The _ union _ ` number | string ` is composed by taking the union _ of the values _ from each type.
316
- > Notice that given two sets with corresponding facts about each set, only the _ intersection _ of those facts applies to the _ union _ of the sets themselves.
317
- > For example, if we had a room of tall people wearing hats, and another room of Spanish speakers wearing hats, after combining those rooms, the only thing we know about _ every _ person is that they must be wearing a hat.
313
+ > 令人困惑的是,类型的 _ 联合 _ 似乎具有这些类型的属性的 _ 交集 _ 。
314
+ > 这并非偶然——联合这个名字来自于类型理论。
315
+ > 联合类型 ` number | string ` 由每种类型的 _ 取值 _ 的并集组成。
316
+ > 请注意,给定两个集合以及每个集合的事实相符,只有这些事实的 _ 交集 _ 适用于集合本身的 _ 并集 _ 。
317
+ > 例如,如果我们有一个房间,里面都是戴着帽子的高个子,另一个房间里讲西班牙语的人都戴着帽子,那么将这些房间组合起来后,我们对 _ 每个 _ 人唯一了解的就是他们一定戴着帽子。
318
318
319
- ## 类型别名
319
+ ## Type Aliases ( 类型别名)
320
320
321
- 我们通过直接在类型注解中编写对象类型和联合类型来使用它们 。
322
- 这很方便,但是常常会想要多次使用同一个类型,并且通过一个名称引用它 。
321
+ 我们一直通过直接在类型注释中编写对象类型和联合类型来使用它们 。
322
+ 但是常常就想要很方便的多次使用同一个类型,并且通过一个名称去引用它 。
323
323
324
- _ 类型别名_ 正是如此 - 任意 _ 类型_ 的一个 _ 名称_ 。
324
+ _ 类型别名_ 正是这样 - 任意 _ 类型_ 的 _ 名称_ 。
325
325
类型别名的语法是:
326
326
327
327
``` ts twoslash
@@ -339,16 +339,16 @@ function printCoord(pt: Point) {
339
339
printCoord ({ x: 100 , y: 100 });
340
340
```
341
341
342
- 实际上,不只是对象类型,你可以使用类型别名为任何类型命名 。
342
+ 实际上,您可以使用类型别名为任何类型命名,而不仅仅是对象类型 。
343
343
例如,类型别名可以命名联合类型:
344
344
345
345
``` ts twoslash
346
346
type ID = number | string ;
347
347
```
348
348
349
- 请注意,别名 _ 只是 _ 别名 - 你不能使用类型别名创建同一类型的不同“版本” 。
350
- 当你使用别名时,它与您编写的别名类型完全一样 。
351
- 换句话说,这段代码 _ 看起来_ 可能是非法的,但是对于 TypeScript 来说是正确的,因为这两种类型都是同一类型的别名 :
349
+ 请注意,别名只是别名 - 您不能使用类型别名来创建同一类型的不同/确定无疑的 ` 版本 ` 。
350
+ 当您使用别名时,就像您编写了别名类型一样 。
351
+ 换句话说,这段代码可能 _ 看起来_ 非法,但根据 TypeScript 是可以的,因为两种类型都是同一类型的别名 :
352
352
353
353
``` ts twoslash
354
354
declare function getInput(): string ;
@@ -360,14 +360,14 @@ function sanitizeInput(str: string): UserInputSanitizedString {
360
360
return sanitize (str );
361
361
}
362
362
363
- // 创建一个经过清理的输入框
363
+ // 创建经过美化的输入
364
364
let userInput = sanitizeInput (getInput ());
365
365
366
- // 仍然可以使用字符串重新赋值
366
+ // 但仍然可以用字符串重新分配
367
367
userInput = " new input" ;
368
368
```
369
369
370
- ## 接口
370
+ ## Interfaces (接口)
371
371
372
372
_ 接口声明_ 是命名对象类型的另一种方式:
373
373
@@ -378,16 +378,16 @@ interface Point {
378
378
}
379
379
380
380
function printCoord(pt : Point ) {
381
- console .log (" The coordinate's x value is " + pt .x );
382
- console .log (" The coordinate's y value is " + pt .y );
381
+ console .log (" x坐标的值为 " + pt .x );
382
+ console .log (" y坐标的值为 " + pt .y );
383
383
}
384
384
385
385
printCoord ({ x: 100 , y: 100 });
386
386
```
387
387
388
- 就像我们上面使用类型别名时一样,这个示例的工作方式就像我们使用了匿名对象类型一样。
389
- TypeScript 只关心我们传递给 ` printCoord ` 的值的结构 - 它只关心它是否具有预期的属性。
390
- 只关心类型的结构和功能,这就是为什么我们说 TypeScript 是一个 _ 结构化类型 _ 的类型系统。
388
+ Just like when we used a type alias above, the example works just as if we had used an anonymous object type.
389
+ TypeScript is only concerned with the _ structure _ of the value we passed to ` printCoord ` - it only cares that it has the expected properties.
390
+ Being concerned only with the structure and capabilities of types is why we call TypeScript a _ structurally typed _ type system.
391
391
392
392
### 类型别名和接口之间的区别
393
393
0 commit comments