typescript 如何定义一个类型为另一个类型的对象?

gkl3eglg  于 2023-02-25  发布在  TypeScript
关注(0)|答案(2)|浏览(205)

我正在使用express和typescript开发一个Rest API。我有一些控制器类,它们的函数充当路由器处理程序。在执行这些函数的过程中,当业务规则没有得到满足时,我可以引发自定义异常,例如“未找到项”或“项已存在”。我使用以下设计完成了这一工作:

//BaseController.ts
interface ErrorMap {
    type: any;
    code: number;
}

export default interface BaseController {
    errorMappings: ErrorMap[]; //allows custom error registration in controllers
}

//CustomError.ts
export default class SampleExistsError extends Error {
    //implementation details...
}

//Custom controller
export default class SampleController implements BaseController {

    async addSampleHandler(req: Request, res: Response): Promise<void> {
        //code that can throw a SampleExistsError...
    }

    errorMappings = [
        //as you see, I want to register the type
        { type: SampleExistsError, code: 400 }
        //there may be other error types registered here here...
    ];
}

//Custom routerErrorMiddleware
import { NextFunction, Request, Response } from "express";
function routerErrorMiddleware(controller: BaseController) {
    return (err: Error, req: Request, res: Response, next: NextFunction) => {
        let handled = false;
        for (const errorMapping of controller.errorMappings) {
            if (err instanceof errorMapping.type) {
                const result = {
                    message: err.message
                };
                handled = true;
                //line below commented because it's not necessary to reproduce the warning/errors
                //res.status(errorMapping.code).json(result);
                break;
            }
        }
        if (!handled) {
            console.log("Error type not found. Looking for next error middleware.");
            next(err);
        }
    };
}

到目前为止一切顺利,设计工作如预期。但后来我得到了一个警告,从linter在这里:

interface ErrorMap {
    type: any //<--- Here's my problem
    code: number
}

我尝试使用这些选项更改定义

//Option 1
interface ErrorMap {
    type: Error; //this breaks the assignment in CustomController
    code: number;
}

//Option 2
interface ErrorMap<T extends Error> {
    type: T; //this breaks the definition in BaseController
    code: number;
}

//Option 3
interface ErrorMap<T extends Error> {
    type: { new(): T }; //same as option 2
    code: number;
}

对于type定义,我可以使用什么来代替any
添加了一个操场来复制警告(它没有显示在操场上,因为我不能在这里定义linter规则)。

yv5phkfx

yv5phkfx1#

通常可以使用unknown代替

icnyk63a

icnyk63a2#

你可以使用特定错误类型的联合来代替任意类型。当你试图使用不正确的错误类型时,这将允许编译器捕捉错误。例如:

interface ErrorMap {
  type: SampleExistsError | ItemNotFoundError;
  code: number;
}

相关问题