【发布时间】:2021-06-14 05:41:23
【问题描述】:
我在一个代码库中,它使用 typescript 在服务器(express)和 react 之间共享 API 接口合同。这些共享类型被组织到命名空间中,运行良好,但在 express 中可能有点冗长。
例如:
// Shared API type in global file
export namespace GetRecordAPI {
export type PathParams = {
recordId: string;
};
export type RequestBody = {};
export type QueryParams = {
date: string;
};
export type Response = APIResponseValidation & {
record: RecordData;
};
}
// Express route controller
type GetRecordHandler = RequestHandler<
GetRecordAPI.PathParams,
GetRecordAPI.Response,
GetRecordAPI.RequestBody,
GetRecordAPI.QueryParams
>;
export const getRecord: GetRecordHandler = async (req, res, next) => {
// ...
};
问题在于为每个快速路由控制器构造RequestHandler 变得非常冗长。由于所有内容都在命名空间中一致地组织,因此我非常希望有一个全局打字稿包装器,通过传递命名空间将它们拼接在一起。
// Global helper
type ExpressHandler<T> = RequestHandler<T.PathParams, T.Response, T.RequestBody, T.QueryParams>;
// Express route controller
export const getRecord: ExpressHandler<GetRecordAPI> = async (req, res, next) => {
// ...
};
这样的事情还有可能吗? React 应用程序独立使用命名空间中的每个导出类型,因此目前最好保留此结构。
【问题讨论】:
-
如果您可以将
namespace作为类型参数传递给泛型类型,这将很容易。不幸的是,我认为这是不可能的。你只会得到error: Cannot use namespace 'GetRecordAPI' as a type。我很想看看是否有人有解决方法! -
如果我写一个答案,我将不得不提及microsoft/TypeScript#9889、microsoft/TypeScript#17588 以及其他几个相关问题(至少间接地)谈论无法以编程方式处理命名空间。跨度>
-
@jcalz 感谢您的示例。我已经开始转向复合类型,但是接口版本有一些优点,并且总体上定义更简洁。谢谢。
标签: typescript express namespaces typescript-generics