|
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