【问题标题】:Override res.end with TypeScript用 TypeScript 覆盖 res.end
【发布时间】:2019-09-28 11:26:25
【问题描述】:

我需要用下一个签名覆盖方法 res.end:

res.end = (data: any, encoding: string)

但是 TS 返回下一个错误:

Type '(data: any, encoding: string) => void' is not assignable to type '{ 
(cb?: (() => void) | undefined): void; 
(chunk: any, cb?: (() => void) | undefined): void; 
(chunk: any, encoding: string, cb?: (() => void) | undefined): void; 
}'.ts(2322)

我曾尝试传递空回调,但没有帮助:

res.end = (data: any, encoding: string, callback: `() =>void`): void

【问题讨论】:

    标签: node.js typescript express


    【解决方案1】:

    问题

    您的初始签名未通过编译器检查,because the end functionServerResponse 继承自 stream.Writable,具有以下重载:

    end(cb?: () => void): void;
    end(chunk: any, cb?: () => void): void;
    end(chunk: any, encoding: string, cb?: () => void): void;
    

    由于end 函数具有该重载,编译器会警告您,在运行时,您需要检查哪些重载正在使用中。

    解决方案

    这是一个类型安全的签名。它检查三个参数中的哪一个是回调,然后采取相应的行动。

    import { Response } from 'express';
    
    const handler = (req: Request, res: Response) => {
    
      res.end = (arg1: Function | any, arg2?: Function | string, arg3?: Function) => {
    
        if (typeof arg1 === 'function') {
          // end(cb?: () => void): void;
        }
    
        if (typeof arg2 === 'function') {
          // end(chunk: any, cb?: () => void): void;
        }
    
        if (typeof arg3 === 'function') {
          // end(chunk: any, encoding: string, cb?: () => void): void;
        }
      }
    };
    

    【讨论】:

    • 其实你应该对arg2使用BufferEncoding。 res.end = (arg1: Function | any, arg2?: Function | BufferEncoding, arg3?: Function) => { .... } ... 谢谢你的回答,对我帮助很大。
    • @M'sieurToph' 感谢您的反馈。你能和我分享一个链接吗,因为我的消息来源显示最终的重载使用string 而不是BufferEncoding。我已在我的答案中添加了指向相关类型的链接。
    • 我没有来源。我的 IDE 告诉我它正在等待 BufferEncoding ;) ...但字符串也有效。找到了类型描述的链接:docs.microsoft.com/en-us/javascript/api/botframework-streaming/… ...但你是对的,我没有找到在 express 中使用的相关来源...这是疯狂的 IDE 告诉我的。
    【解决方案2】:

    将你的函数类型设为any,这意味着它可以转换(或赋值)为任何类型。

    试试这个

    res.end = ((data: any, encoding: string): void => { }) as any;
    

    更新

    您可以创建一个扩展express.Response 的类型,它会覆盖end 方法(NodeJS.WritableStream 的方法)。

    import { Request, Response, Handler } from 'express';
    
    type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
    
    interface MyResponse extends Omit<Response, "end"> {
      end: (data: any, encoding: string) => void;
    }
    
    const handler: Handler = (req: Request, res: MyResponse) => {
      res.end = (data: any, encoding: string) => {
    
      }
    };
    

    【讨论】:

    • 这隐藏了在运行时检查存在哪个参数列表的重要需求。
    • 创建MyResponse 的方法只有在调用handler 知道end 的新签名时才能可靠地工作。
    猜你喜欢
    • 2016-05-23
    • 2018-02-15
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2016-03-18
    • 2023-03-21
    • 1970-01-01
    相关资源
    最近更新 更多