1+ import type { AnyClass } from "./type"
2+
13type Success < T > = {
24 data : T
35 error : null
@@ -14,61 +16,61 @@ type Failure<E> = {
1416 error : E
1517]
1618
17- type Result < T , E extends unknown = Error > = Success < T > | Failure < E >
19+ type Result < T , E = any > = Success < T > | Failure < E >
1820
1921interface tryCatch {
20- < T > ( arg : Promise < T > ) : Promise < Result < T > >
21- < V > ( arg : ( ( ) => V ) ) : Result < V >
22+ // 捕获所有
23+ < T > ( func : ( ( ) => T ) ) : Result < T >
24+ < T > ( asyncFunc : Promise < T > ) : Promise < Result < T > >
25+ // 捕获指定
26+ < T , E extends AnyClass > ( func : ( ( ) => T ) , catchClass : E ) : Result < T , InstanceType < E > >
27+ < T , E extends AnyClass > ( func : Promise < T > , catchClass : E ) : Promise < Result < T , InstanceType < E > > >
2228}
2329
2430/**
25- * 尝试执行一个函数或Promise,返回一个包含执行结果或错误信息的复合对象
31+ * 尝试执行一个函数或Promise,返回一个对象,其中包含执行结果或被捕获的错误
2632 *
2733 * 该对象同时支持对象属性访问(.data/.error)和数组索引访问([0]/[1])两种方式
2834 *
29- * @param parameter 一个函数或者Promise对象
30- * @returns 返回参数中,data和[0]是函数的返回值或是Promise的解析结果,error和[1]是错误对象。两者将有一为`null`
35+ * @param func 一个函数或者Promise对象
36+ * @param catchClass 要捕获的错误类型(含子类),如果不指定,则捕获所有错误;如指定,则为被捕获的错误将继续上抛
37+ * @returns 返回一个如后方例的对象`{ data, error } & [ data, error ]`
3138 *
3239 * @example
3340 * tryCatch(() => func(...))
3441 * // => [data, error] & {data, error}
3542 * // data: func的返回值,error:函数执行过程中发生的错误
3643 *
44+ *
45+ * @example
46+ * tryCatch(() => func(...), TypeError)
47+ * // => [data, error] & {data, error}
48+ * // data: func的返回值,error:函数执行过程中,发生的TypeError或其子类错误
49+ *
3750 * @example
3851 * await tryCatch(asyncFunc(...))
3952 * // => [data, error] & {data, error}
40- * // data: asyncFunc的返回值 ,error:asyncFunc执行过程中发生的错误
53+ * // data: 异步函数asyncFunc的返回值 ,error:asyncFunc执行过程中发生的错误
4154 */
42- export const tryCatch : tryCatch = ( parameter : any ) : any => {
43-
44- // 处理 Promise
45- if ( typeof parameter === "object" ) {
46- return ( parameter as Promise < any > )
47- . then ( data => Object . assign ( [ data , null ] , { data, error : null } ) )
48- . catch ( error => Object . assign ( [ null , error ] , { data : null , error } ) )
49- }
55+ export const tryCatch : tryCatch = ( func : Function | Promise < any > , catchClass ?: any ) : any => {
5056
5157 // 处理函数
52- if ( typeof parameter === "function" ) {
58+ if ( typeof func === "function" ) {
5359 try {
54- const data = parameter ( )
60+ const data = func ( )
5561 return Object . assign ( [ data , null ] , { data, error : null } )
5662 } catch ( error ) {
57- return Object . assign ( [ null , error ] , { data : null , error } )
63+ if ( ! catchClass || error instanceof catchClass ) return Object . assign ( [ null , error ] , { data : null , error } )
64+ throw error
5865 }
59- }
60-
61- throw new TypeError ( "参数类型错误,应为 Promise 或函数" )
62- }
66+ } else {
67+ // 处理 Promise,兼容第三方Promise实现
68+ return func
69+ . then ( data => Object . assign ( [ data , null ] , { data, error : null } ) )
70+ . catch ( error => {
71+ if ( ! catchClass || error instanceof catchClass ) return Object . assign ( [ null , error ] , { data : null , error } )
72+ throw error
73+ } )
6374
64- // import fs from "node:fs/promises"
65- // (async () => {
66- // const a = await tryCatch(fs.stat("a.txt"))
67- // console.log(typeof a)
68- // })()
69- // console.log(a)
70- // if (!a.error) {
71- // console.log(a.error)
72- // } else {
73- // console.log(a.data)
74- // }
75+ }
76+ }
0 commit comments