Skip to content

Commit 98936e5

Browse files
committedJul 18, 2023
docs: finish chapter object
1 parent 739e363 commit 98936e5

File tree

3 files changed

+39
-37
lines changed

3 files changed

+39
-37
lines changed
 

‎chapters.yml

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
- tuple.md: 元组
77
- symbol.md: symbol 类型
88
- function.md: 函数
9+
- object.md: 对象

‎docs/any.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,20 @@ function add(x, y) {
5050
return x + y;
5151
}
5252

53-
add(1, [1, 2, 3]) // 正确
53+
add(1, [1, 2, 3]) // 不报错
5454
```
5555

5656
上面示例中,函数`add()`的参数变量`x``y`,都没有足够的信息,TypeScript 无法推断出它们的类型,就会认为这两个变量和函数返回值的类型都是`any`。以至于后面就不再对函数`add()`进行类型检查了,怎么用都可以。
5757

5858
这显然是很糟糕的情况,所以对于那些类型不明显的变量,一定要显式声明类型,防止被推断为`any`
5959

60-
TypeScript 提供了一个编译选项`--noImplicitAny`,打开该选项,只要推断出`any`类型就会报错。
60+
TypeScript 提供了一个编译选项`noImplicitAny`,打开该选项,只要推断出`any`类型就会报错。
6161

6262
```bash
6363
$ tsc --noImplicitAny app.ts
6464
```
6565

66-
上面命令使用了`--noImplicitAny`编译选项进行编译,这时上面的函数`add()`就会报错。
66+
上面命令使用了`noImplicitAny`编译选项进行编译,这时上面的函数`add()`就会报错。
6767

6868
### 污染问题
6969

@@ -73,10 +73,10 @@ $ tsc --noImplicitAny app.ts
7373
let x:any = 'hello';
7474
let y:number;
7575

76-
y = x; // 正确
76+
y = x; // 不报错
7777

78-
y * 123 // 正确
79-
y.toFixed() // 正确
78+
y * 123 // 不报错
79+
y.toFixed() // 不报错
8080
```
8181

8282
上面示例中,变量`x`的类型是`any`,实际的值是一个字符串。变量`y`的类型是`number`,表示这是一个数值变量,但是它被赋值为`x`,这时并不会报错。然后,变量`y`继续进行各种数值运算,TypeScript 也检查不出错误,问题就这样留到运行时才会暴露。
@@ -207,9 +207,9 @@ function f():never {
207207
throw new Error('Error');
208208
}
209209

210-
let v1:number = f(); // 正确
211-
let v2:string = f(); // 正确
212-
let v3:string = f(); // 正确
210+
let v1:number = f(); // 不报错
211+
let v2:string = f(); // 不报错
212+
let v3:string = f(); // 不报错
213213
```
214214

215215
上面示例中,函数`f()`会抛错,所以返回值类型可以写成`never`,即不可能返回任何值。各种其他类型的变量都可以赋值为`f()`的运行结果(`never`类型)。

‎docs/object.md

+29-28
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
对象类型的最简单声明方法,就是使用大括号表示对象,在大括号内部声明每个属性和方法的类型。
88

99
```typescript
10-
const obj:{
10+
const obj:{
1111
x:number;
12-
y:number;
12+
y:number;
1313
} = { x: 1, y: 1 };
1414
```
1515

@@ -36,9 +36,9 @@ type MyObj = {
3636
一旦声明了类型,对象赋值时,就不能缺少指定的属性,也不能有多余的属性。
3737

3838
```typescript
39-
type MyObj = {
39+
type MyObj = {
4040
x:number;
41-
y:number;
41+
y:number;
4242
};
4343

4444
const o1:MyObj = { x: 1 }; // 报错
@@ -50,9 +50,9 @@ const o2:MyObj = { x: 1, y: 1, z: 1 }; // 报错
5050
读写不存在的属性也会报错。
5151

5252
```typescript
53-
const obj:{
53+
const obj:{
5454
x:number;
55-
y:number;
55+
y:number;
5656
} = { x: 1, y: 1 };
5757

5858
console.log(obj.z); // 报错
@@ -83,13 +83,13 @@ const obj:{
8383
add(x:number, y:number): number;
8484
// 或者写成
8585
// add: (x:number, y:number) => number;
86-
} = {
87-
x: 1,
88-
y: 1,
86+
} = {
87+
x: 1,
88+
y: 1,
8989
add(x, y) {
9090
return x + y;
91-
}
92-
};
91+
}
92+
};
9393
```
9494

9595
上面示例中,对象`obj`有一个方法`add()`,需要定义它的参数类型和返回值类型。
@@ -110,9 +110,9 @@ type Name = User['name']; // string
110110

111111
```typescript
112112
// 写法一
113-
type MyObj = {
113+
type MyObj = {
114114
x:number;
115-
y:number;
115+
y:number;
116116
};
117117

118118
const obj:MyObj = { x: 1, y: 1 };
@@ -123,7 +123,7 @@ interface MyObj {
123123
y: number;
124124
}
125125

126-
const obj:MyObj = { x: 1, y: 1 };
126+
const obj:MyObj = { x: 1, y: 1 };
127127
```
128128

129129
上面示例中,写法一是`type`命令的用法,写法二是`interface`命令的用法。`interface`命令的详细解释,以及与`type`命令的区别,详见《Interface》一章。
@@ -148,9 +148,9 @@ const obj:MyInterface = { // 正确
148148
如果某个属性是可选的(即可以忽略),需要在属性名后面加一个问号。
149149

150150
```typescript
151-
const obj: {
151+
const obj: {
152152
x: number;
153-
y?: number;
153+
y?: number;
154154
} = { x: 1 };
155155
```
156156

@@ -200,11 +200,11 @@ if (user.lastName !== undefined) {
200200
}
201201
```
202202

203-
上面示例中,`lastName`是可选属性,需要判断是否为`undefined`以后,才能使用。建议可以使用下面的写法
203+
上面示例中,`lastName`是可选属性,需要判断是否为`undefined`以后,才能使用。建议使用下面的写法
204204

205205
```typescript
206206
// 写法一
207-
let firstName = (user.firstName === undefined)
207+
let firstName = (user.firstName === undefined)
208208
? 'Foo' : user.firstName;
209209
let lastName = (user.lastName === undefined)
210210
? 'Bar' : user.lastName;
@@ -286,7 +286,7 @@ interface Person {
286286
name: string;
287287
age: number;
288288
}
289-
289+
290290
interface ReadonlyPerson {
291291
readonly name: string;
292292
readonly age: number;
@@ -344,12 +344,12 @@ const obj:MyObj = {
344344
foo: 'a',
345345
bar: 'b',
346346
baz: 'c',
347-
};
347+
};
348348
```
349349

350350
上面示例中,类型`MyObj`的属性名类型就采用了表达式形式,写在方括号里面。`[property: string]``property`表示属性名,这个是可以随便起的,它的类型是`string`,即属性名类型为`string`。也就是说,不管这个对象有多少属性,只要属性名为字符串,且属性值也是字符串,就符合这个类型声明。
351351

352-
属性名(即上例的`property`)的类型有三种可能,除了上例的`string`,还有`number``symbol`
352+
JavaScript 对象的属性名(即上例的`property`)的类型有三种可能,除了上例的`string`,还有`number``symbol`
353353

354354
```typescript
355355
type T1 = {
@@ -430,7 +430,7 @@ const {id, name, price} = product;
430430
const {id, name, price}:{
431431
id: string;
432432
name: string;
433-
price: number
433+
price: number
434434
} = product;
435435
```
436436

@@ -520,7 +520,7 @@ function getSum(obj:myObj) {
520520
}
521521
```
522522

523-
上面示例中,函数`getSum()`要求传入参数的类型是`myObj`,但是实际上所有与`myObj`兼容的对象都可以传入。这会导致`const v = obj[n]`这一行会报错,原因是`obj[n]`取出的属性值不一定是数值(`number`),使得变量`v`的类型是`any`如果不允许变量类型推断为`any`,代码就会报错。如果写成下面这样,就不会报错。
523+
上面示例中,函数`getSum()`要求传入参数的类型是`myObj`,但是实际上所有与`myObj`兼容的对象都可以传入。这会导致`const v = obj[n]`这一行报错,原因是`obj[n]`取出的属性值不一定是数值(`number`),使得变量`v`的类型被推断为`any`如果项目设置为不允许变量类型推断为`any`,代码就会报错。写成下面这样,就不会报错。
524524

525525
```typescript
526526
type MyObj = {
@@ -569,7 +569,7 @@ const point:{
569569

570570
上面示例中,等号右边是一个变量,就不会触发严格字面量检查,从而不报错。
571571

572-
TypeScript 对字面量进行严格检查的目的,主要是防止拼写错误。一般来说,字面量大多数来自手写,容易出现拼写错误,或者误用了 API。
572+
TypeScript 对字面量进行严格检查的目的,主要是防止拼写错误。一般来说,字面量大多数来自手写,容易出现拼写错误,或者误用 API。
573573

574574
```typescript
575575
type Options = {
@@ -603,7 +603,7 @@ const Obj:Options = myOptions;
603603
```typescript
604604
const Obj:Options = {
605605
title: '我的网页',
606-
darkmode: true,
606+
darkmode: true,
607607
} as Options;
608608
```
609609

@@ -638,7 +638,7 @@ computeDistance({x: 1, y: 2}); // 正确
638638

639639
上面示例中,对象字面量传入函数`computeDistance()`时,不能有多余的属性,否则就通不过严格字面量检查。
640640

641-
编译器选项`suppressExcessPropertyErrors`可以在`tsconfig.json`文件里面关闭多余属性检查
641+
编译器选项`suppressExcessPropertyErrors`可以关闭多余属性检查。下面是它在 tsconfig.json 文件里面的写法
642642

643643
```typescript
644644
{
@@ -745,9 +745,9 @@ d = 'hello';
745745
d = 2;
746746
```
747747

748-
上面示例中,各类类型的值(除了`null``undefined`)都可以赋值给空对象类型,跟`Object`类型的行为是一样的。
748+
上面示例中,各种类型的值(除了`null``undefined`)都可以赋值给空对象类型,跟`Object`类型的行为是一样的。
749749

750-
由于空对象是`Object`类型的简写,所以它不会有严格字面量检查,赋值时总是允许多余的属性,只是不能读取这些属性。
750+
因为`Object`可以接受各种类型的值,而空对象是`Object`类型的简写,所以它不会有严格字面量检查,赋值时总是允许多余的属性,只是不能读取这些属性。
751751

752752
```typescript
753753
interface Empty { }
@@ -769,3 +769,4 @@ const a:WithoutProperties = { prop: 1 };
769769
```
770770

771771
上面的示例中,`[key: string]: never`表示字符串属性名是不存在的,因此其他对象进行赋值时就会报错。
772+

0 commit comments

Comments
 (0)