TypeScript如何为Express路由控制器定义无固定名称的通配类方法?
TypeScript 没有你示例中写的通配抽象方法语法,但可以通过以下两种常用方案实现所有非固定名称方法的类型约束:
方案1:类索引签名约束所有成员类型
先统一定义公共类型,再通过索引签名约束类的所有成员类型:
import { Request, Response, NextFunction } from "express"; // 路由处理函数的标准类型 type RouteHandler = (request: Request, response: Response, next: NextFunction) => void; // 路由声明类型 type RouteDeclaration = { path: string; method: "get" | "post" | "put" | "delete" | "patch"; action: RouteHandler; };
抽象类实现如下:
abstract class RouteController { // 强制要求子类实现 get 方法,返回路由声明数组 abstract get(): RouteDeclaration[]; // 索引签名:约束所有字符串命名的类成员,要么是 get 方法类型,要么是合法路由处理函数类型 [key: string]: RouteHandler | (() => RouteDeclaration[]); }
效果:子类继承该抽象类后,所有字符串命名的公共/受保护成员如果是函数,必须符合上述两种类型之一,参数和返回值不符合时会直接抛出类型错误。
注意:私有方法(private 修饰)不受索引签名约束,如果需要约束私有路由方法,要么改为 public/protected 修饰,要么手动给私有方法加类型注解:
private ping: RouteHandler = (_, response) => { response.status(200).send({ message: "Pong!" }); }
方案2:路由声明兜底校验
如果你不想约束类的所有成员,只需要保证最终注册到路由的方法符合类型要求,可以直接在 RouteDeclaration 的 action 字段固定类型为 RouteHandler,子类实现 get 方法返回路由数组时,如果传入的方法参数/返回值不符合要求,TS 会直接报错,不需要额外约束类的所有成员。
两种方案可以搭配使用,索引签名约束类内所有方法的写法,路由声明类型做最终注册前的兜底校验,完全可以覆盖你要的约束效果。
内容的提问来源于stack exchange,提问作者Cholewka
相关产品推荐
相关产品推荐

