Lack of Type Safety When Extending Express API with Custom Response Methods

Hi Express community, I'm exploring the feature of extending the Express API, as documented here, to add custom response methods. While this is a powerful feature, I've encountered what appears to be a lack of type safety when implementing these custom methods, particularly when using TypeScript. For example, I've defined a custom AuthUser type:
type AuthUser = {
id: number;
name: string;
};
type AuthUser = {
id: number;
name: string;
};
And extended the express.Response object with a custom success method:
// express.d.ts
/* eslint-disable ts/consistent-type-definitions */

import type { Send } from 'express';

declare global {
export type Success<T = any> = {
code: number;
data: T;
message: string;
};
export namespace Express {
export interface Response<ResBody = any> {
respond: (body: ResBody) => ReturnType<Send<ResBody>>;
success: (code: number, message: string, data: ResBody extends Success<infer T> ? T : never) => ReturnType<Send<ResBody>>;
}
}
}
// express.d.ts
/* eslint-disable ts/consistent-type-definitions */

import type { Send } from 'express';

declare global {
export type Success<T = any> = {
code: number;
data: T;
message: string;
};
export namespace Express {
export interface Response<ResBody = any> {
respond: (body: ResBody) => ReturnType<Send<ResBody>>;
success: (code: number, message: string, data: ResBody extends Success<infer T> ? T : never) => ReturnType<Send<ResBody>>;
}
}
}
// app.ts
import type { Request, Response } from 'express';

import express from 'express';

const app = express();

type AuthedUser = {
id: number;
name: string;
};

app.get('/', (_req: Request, res: Response<Success<AuthedUser>>) => {
console.warn('Hello World!');
// this should be an error but it's not
res.success(200, 'success', 1);
// this is working fine
res.send({
code: 200,
data: 1,
message: 'success',
});
});

app.response.respond = function (body: any) {
return this.send(body);
};

app.response.success = function (code: number, message?: string, data?: any) {
return this.respond({
code,
data,
message,
});
};

export default app;
// app.ts
import type { Request, Response } from 'express';

import express from 'express';

const app = express();

type AuthedUser = {
id: number;
name: string;
};

app.get('/', (_req: Request, res: Response<Success<AuthedUser>>) => {
console.warn('Hello World!');
// this should be an error but it's not
res.success(200, 'success', 1);
// this is working fine
res.send({
code: 200,
data: 1,
message: 'success',
});
});

app.response.respond = function (body: any) {
return this.send(body);
};

app.response.success = function (code: number, message?: string, data?: any) {
return this.respond({
code,
data,
message,
});
};

export default app;
Now, this should provide type-safety but lack 2 (see attachment image) generic missing from express types. so My question is that is it valid and if yes then can someone guild me to make first OS PR to express's types. if not then how can i archive this?. Thanks.
No description
0 Replies
No replies yetBe the first to reply to this messageJoin

Did you find this page helpful?