好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

一个我认为最好使用 Result 类型进行 TypeScript 错误处理的故事

介绍

当我在寻找处理 TypeScript 错误的好方法时,我发现了以下文章。

当我结合本文描述的方法编写代码时,我个人觉得很爽,所以想传播一下。 ?

使用 Result 类型可以让您摆脱抛出异常的痛苦

当我解释这种方法的优点时,我在使用标准的“抛出异常”方法(如上面的文章中所写)时感到以下痛苦。

不是类型安全的(不知道类型会不会抛出异常) 难以处理(抛出的异常必须被捕获和处理) 测试很困难(在 Jest 中,您必须使用 toThrow() 、 toThrowError() 等进行评估)

通过使用 Result 类型和“返回错误对象”,这些痛苦都得到了解决。

结果类型的使用

首先,创建一个 Result 类型。

  type   Result  <  T  ,   E   extends   Error  >   =   Success  <  T  >   |   Failure  <  E  >  ; 

 class   Success  <  T  >   { 
   readonly   value  :   T  ; 

   constructor  (  value  :   T  )   { 
     this  .  value   =   value  ; 
   } 
   isSuccess  ():   this   is   Success  <  T  >   { 
     return   true  ; 
   } 
   isFailure  ():   this   is   Failure  <  Error  >   { 
     return   false  ; 
   } 
 } 

 class   Failure  <  E   extends   Error  >   { 
   readonly   error  :   E  ; 

   constructor  (  error  :   E  )   { 
     this  .  error   =   error  ; 
   } 
   isSuccess  ():   this   is   Success  <  unknown  >   { 
     return   false  ; 
   } 
   isFailure  ():   this   is   Failure  <  E  >   { 
     return   true  ; 
   } 
 } 
 

接下来,决定返回错误响应的格式。

例如,当发生错误时,可以方便地在对象中收集必要的信息。

将以下内容添加到 Error 对象有助于与前端链接和跟踪错误。

functionName ⇒ 发生错误的函数名 statusCode ⇒ HTTP 状态码 code ⇒ 开发人员识别的错误代码

  class   ErrorResponse   extends   Error   { 
   readonly   name  :   string 
   readonly   message  :   string 
   readonly   stack  ?:   string 

   constructor  ( 
      readonly   functionName  :   string   =   '  unknown functionName  '  , 
      readonly   statusCode  :   number   =   500  , 
      readonly   code  :   string  =   '  APP_UNKNOWN_ERROR  '  ,  
      readonly   error  :   Error   =   new   Error  (  '  unknown error  '  ))   { 
        super  () 
        this  .  name   =   error  .  name 
        this  .  message   =   error  .  message 
        this  .  stack   =   error  .  stack 
      } 
 } 
 

如果是自己创建的函数,可以设置 new Failure() 为返回值,如下。

  function   foo  (  m  :   string  ):   Result  <  string  ,   ErrorResponse  >   { 
   if   (  m   ===   '  m  '  )   { 
     return   new   Success  (  '  success  '  ) 
   }   else   { 
     return   new   Failure  (  new   ErrorResponse  (  foo  .  name  ,   500  ,   '  APP_FOO_FUNCTION_ERROR  '  )) 
   } 
 } 
 

如果您想在使用某些第三方库的实现中将 new Failure() 设置为返回值,请使用 try-catch 将 new Failure() 设置为返回值。

  function   bar  (  m  :   string  ):   Result  <  string  ,   ErrorResponse  >   { 
   try   { 
	 // なにかしらサードパーティ製ライブラリをつかった実装 
   }   catch  (  err  )   { 
     if   (  err   instanceof   Error  )   { 
       return   new   Failure  (  new   ErrorResponse  (  bar  .  name  ,   500  ,   '  APP_ERROR  '  ,   err  )) 
     } 
     return   new   Failure  (  new   ErrorResponse  (  bar  .  name  )) 
   } 
 } 
 

通过在发生错误时返回对象,您不必在测试中使用错误匹配器( toThrow() 、 toThrowError() ),并且可以使用 toBe() 或 toEqual 进行评估。

  const   result   =   foo  (  '  a  '  ) 

 expect  (  result  .  isFailure  ()   ?   result  .  error  .  statusCode   :   undefined  ).  toBe  (  500  ) 
 expect  (  result  .  isFailure  ()   ?   result  .  error  .  code   :   undefined  ).  toBe  (  '  APP_FOO_FUNCTION_ERROR  '  ) 
 

综上所述

使用 try-catch 抛出异常的方法对人类来说是不是太早了???

异常应作为 Result 类型的错误对象返回。 ???


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308623895.html

查看更多关于一个我认为最好使用 Result 类型进行 TypeScript 错误处理的故事的详细内容...

  阅读:57次