|
13 | 13 |
|
14 | 14 | ## try-catch 块级作用域带来的问题
|
15 | 15 |
|
| 16 | +先看一段代码: |
| 17 | + |
16 | 18 | ```ts
|
| 19 | +const somePromise = Promise.resolve({ prop: 'value' }); |
| 20 | + |
| 21 | +try { |
| 22 | + // 块级作用域内赋值 |
| 23 | + // res类型推断为 {prop: string} |
| 24 | + const res = await somePromise; |
| 25 | + // 类型安全地使用 res |
| 26 | + console.log(res.prop); // 'value' |
| 27 | +} catch (err) { |
| 28 | + // 此处 err 类型为 unknown |
| 29 | + console.log(err); |
| 30 | +} |
| 31 | +``` |
| 32 | + |
| 33 | +但有些时候,我们需要将变量的声明提升到块级作用域外,比如: |
| 34 | + |
| 35 | +```ts |
| 36 | +const somePromise = Promise.resolve({ prop: 'value' }); |
| 37 | + |
17 | 38 | // 需要先在 try-catch 块级作用域外定义变量,此处还需要先声明类型
|
| 39 | +// 由于只提升了声明,但没有提升赋值,需要捕捉期望的返回值类型,并联合 undefined |
| 40 | +type Result = typeof somePromise extends Promise<infer T> ? T : never; |
18 | 41 | let res: Result | undefined;
|
19 | 42 |
|
20 | 43 | try {
|
21 | 44 | // 块级作用域内赋值
|
22 | 45 | res = await somePromise;
|
| 46 | + // 块级作用域内类型仍然安全 |
| 47 | + console.log(res.prop); // 'value' |
23 | 48 | } catch (err) {
|
24 | 49 | // 此处 err 类型为 unknown
|
25 | 50 | console.log(err);
|
26 |
| - return; |
27 | 51 | }
|
28 | 52 |
|
| 53 | +// 其他操作... |
| 54 | + |
29 | 55 | // try-catch 块级作用域外使用该变量
|
30 |
| -// 因为 res 类型包含 undefined,所以还要加有值判断 |
| 56 | +// 此处 res 类型包含 undefined,类型使用不安全 |
| 57 | +console.log(res.prop); // TS18048: 'res' is possibly 'undefined'. |
| 58 | +// 所以还要加有值判断 |
31 | 59 | if (res) {
|
32 | 60 | console.log(res.prop);
|
33 | 61 | }
|
34 | 62 | ```
|
35 | 63 |
|
| 64 | +可以看到,由于块级作用域的特性,导致 res 的类型被”污染“了, 使用 try-flatten 后,你将可以用一种“扁平化”的方式调用 try-catch, 不用为了类型安全写一些冗余代码。 |
| 65 | + |
36 | 66 | ## 用上 `try-flatten` 后
|
37 | 67 |
|
38 | 68 | ```ts
|
39 |
| -const [err, res] = await somePromise; |
| 69 | +const [err, res] = await tryFlatten(somePromise); |
40 | 70 |
|
41 | 71 | // 只需要判断 err 是否存在即可
|
42 | 72 | if (err) {
|
43 | 73 | // 此处 err 类型为 Error,res 类型为 undefined
|
44 |
| - console.log(err instanceof Error); |
45 |
| - console.log(res === undefined); |
| 74 | + console.log(err instanceof Error); // true |
| 75 | + console.log(res === undefined); // true |
46 | 76 | return;
|
47 | 77 | }
|
48 | 78 |
|
49 | 79 | // 此处 err 类型为 null,res 类型为 Result
|
50 |
| -console.log(err === null); |
51 |
| -console.log(res.prop); |
| 80 | +console.log(err === null); // true |
| 81 | +console.log(res.prop); // 'value' |
52 | 82 | ```
|
53 | 83 |
|
54 | 84 | # 下载安装
|
|
0 commit comments