我正试图在我的Express项目中获得一些更智能的打字,但我在扩展Response.render
功能时遇到了麻烦。
import { Response } from "express";
import { Product } from "../models/Product.interface";
export interface ProductListResponse extends Response {
render: (view: string, options?: { products: Product[] }) => void;
}
原点定义如下:
render(view: string, options?: object, callback?: (err: Error, html: string) => void): void;
render(view: string, callback?: (err: Error, html: string) => void): void;
当我试图编译这个时,我得到
src/routes/product.interface.ts:13:18 - error TS2430: Interface 'ProductListResponse' incorrectly extends interface 'Response<any, Record<string, any>>'.
Types of property 'render' are incompatible.
Type '(view: string, options: { products: Product[]; }) => void' is not assignable to type '{ (view: string, options?: object, callback?: (err: Error, html: string) => void): void; (view: string, callback?: (err: Error, html: string) => void): void; }'.
Types of parameters 'options' and 'callback' are incompatible.
Property 'products' is missing in type '(err: Error, html: string) => void' but required in type '{ products: Product[]; }'.
13 export interface ProductListResponse extends Response {
~~~~~~~~~~~~~~~~~~~
src/routes/product.interface.ts:14:37
14 render(view: string, options: { products: Product[] }): void;
~~~~~~~~
'products' is declared here.
Found 2 errors.
我认为我可以通过扩展基本接口来覆盖render
的定义,但显然这不是真的。任何帮助都将非常感激。谢谢!
您可以在express的Response类型中省略render
定义。然后,重新定义渲染函数:
interface ProductListResponse extends Omit<Response, 'render'> {
render: (view: string, options?: { products: Product[] }) => void;
}
您需要将Response
接口的.render()
方法重载签名添加到您的自定义ProductListResponse
接口中。
import express, { Response } from 'express';
interface Product {}
export interface ProductListResponse extends Response {
render(view: string, options?: { products: Product[] }): void;
render(view: string, options?: object, callback?: (err: Error, html: string) => void): void;
render(view: string, callback?: (err: Error, html: string) => void): void;
}
const app = express();
app.get('/', (req, res: ProductListResponse) => {
res.render('index', { products: [] });
});
或者,使用交集类型
import express, { Response } from 'express';
interface Product {}
export interface ProductListResponse {
render(view: string, options?: { products: Product[] }): void;
}
const app = express();
app.get('/', (req, res: ProductListResponse & Response) => {
res.render('index', { products: [] });
});
TypeScript version:4.4.4