V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
a132811
V2EX  ›  TypeScript

ts 有办法隐式修改 class constructor 的类型吗?

  •  
  •   a132811 · 2023-02-23 13:11:39 +08:00 · 1251 次点击
    这是一个创建于 671 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想给 callable object 加上 function 类型提示

    // refer to: https://medium.com/@adrien.za/creating-callable-objects-in-javascript-fbf88db9904
    class Callable extends Function {
      constructor() {
        super('return arguments.callee._call(...arguments)')
      }
    }
    class AjaxFactory extends Callable{
      constructor(){
        super()
      }
      _call(url:string, init?:RequestInit) {
        //middleware(init)
        return fetch(url, init)
      }
      //use(middleware){...}
    }
    

    每次创建新对象时,调用方总是要类型转换一下,才能获得类型提示

    type AjaxFactoryF = AjaxFactory & AjaxFactory['_call']
    
    const request=<AjaxFactoryF>(new AjaxFactory()) //使用方要进行一下类型转换
    
    //request.use(middleware)
    request('http://x.com').then(resp=>console.log(resp))
    

    有办法简化吗?隐式修改 class constructor 的类型?

    2 条回复    2023-06-19 07:40:58 +08:00
    a132811
        1
    a132811  
    OP
       2023-03-08 20:08:04 +08:00
    可加一个 alias 中间变量:AjaxFactoryAlias ,给中间变量带上扩展的类型 AjaxFactoryF


    type AjaxFactoryF = AjaxFactory & AjaxFactory['_call']
    const AjaxFactoryAlias = AjaxFactory as new ()=>AjaxFactoryF
    export {AjaxFactoryAlias as AjaxFactory}
    chnwillliu
        2
    chnwillliu  
       2023-06-19 07:40:58 +08:00   ❤️ 1
    可以用同名 interface 来声明实例类型。

    ```typescript
    abstract class Callable<T extends (...args:any[]) => any> extends Function {
    constructor() {
    super('return arguments.callee._call(...arguments)');
    }
    protected abstract _call(...args: Parameters<T>): ReturnType<T>;
    }

    interface Callable<T extends (...args:any[]) => any> extends Function {
    (...args: Parameters<T>): ReturnType<T>
    }

    class AjaxFactory extends Callable<(url: string, init?:RequestInit) => Promise<any>> {
    protected override _call(url: string, init?:RequestInit): Promise<any> {
    return fetch(url, init)
    }
    }

    const request = new AjaxFactory();

    request('/test', {method:'GET'})
    ```

    https://www.typescriptlang.org/play?ssl=20&ssc=33&pln=1&pc=1#code/IYIwzgLgTsDGEAJYBthjAgwsZqTIFMAeAFQQIA8ICA7AEwwAoA6V4KAczAC5gaBPANoBdAJQIAvAD4EffjMrV6GAGIBXGvACWAexoIA3gFgAUAnNI9kKGvg6ojccbMXXYNQAcCDgORQCEGpQ+uwcagC2tBBgzLA4hATMAPpxuCxsnBFRYKI+ogDcpq4AvkUWHlA61PAEdLLg0HCIKfHpzKE8CAAK7MCR1FBgpFKi3AgASgFBNCT8XsOFJqUmplo0AwBmcARY8aCEpORUtAwIbR28AiLi0rICCsfKCOqaELr6zq7nnJ09MP3eIYkEZjSaBYKzebA0zLUwoNAYACCACtgBQVE17PwjkpTthcPtiIwgsgxtY1hwADQINZaCAAfm4kwAjmoCJAAJI0Ok3GRdSrhLRgYhyKQyT7lSrVah1HQAN28UC0dB2LTSJLJ0Ap1NpDKZBFZ7IgXJ5Y35OkFwqIosMZVc5n84P0GwCsAAFsSoMgddyIKI7QhlrCTLArIh-IbIJIEDQCAB3BAotEYuxQfiORamCNsyCMHwAemokB81IM-TdOjo3B8AHEAKIkHzFURAA
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3092 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:14 · PVG 21:14 · LAX 05:14 · JFK 08:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.