Javascript 子类作为参数的Typescript定义

Javascript 子类作为参数的Typescript定义,javascript,typescript,Javascript,Typescript,我试图为写一个类型定义,但我不完全理解应该如何写它。 要点是我们应该对Store、Actions和Flummox类进行子类化,并将它们传递给函数。 下面是一个包含操作的代码示例: import { Flummox, Actions, Store } from 'flummox'; class MessageActions extends Actions { newMessage(content: string) { return content; } } class Messa

我试图为写一个类型定义,但我不完全理解应该如何写它。 要点是我们应该对Store、Actions和Flummox类进行子类化,并将它们传递给函数。
下面是一个包含操作的代码示例:

import { Flummox, Actions, Store } from 'flummox';
class MessageActions extends Actions {
  newMessage(content: string) {
    return content;
  }
 }
class MessageStore extends Store {
   constructor(flux: Flummox) {
   super();

   const messageActions: MessageActions = flux.getActions('messages'); // error here
   this.register(messageActions.newMessage, this.handleNewMessage);
  }
 }

 class Flux extends Flummox {
   constructor() {
     super();

     this.createActions('messages', MessageActions);
     this.createStore('messages', MessageStore, this); //error here
   }
 }
我开始的定义是:

/// <reference path="eventemitter3.d.ts"/>

declare module "flummox" {

  type ActionId = string;

  class Store {
    register(action: ActionId | Function, handler: Function): void;
  }

  class Actions {

  }

  class Flummox extends EventEmitter3.EventEmitter.EventEmitter3 {
    createActions(key: string, actions: Actions, constructorArgs?: any | any[]): Actions;
    getActions(key: string): Actions;
    removeActions(key: string): Actions;

    createStore(key: string, store: Store, constructorArgs?: any | any[]): Store;
    getStore(key: string): Store;
    removeStore(key: string): Store;
 }
}
//
声明模块“flummox”{
类型ActionId=string;
班级商店{
寄存器(action:ActionId | Function,handler:Function):void;
}
集体诉讼{
}
类Flummox扩展了EventEmitter3.EventEmitter.EventEmitter3{
createActions(键:字符串,操作:操作,构造函数args?:any | any[]):操作;
getActions(键:字符串):操作;
removeActions(键:字符串):操作;
createStore(key:string,store:store,constructorArgs?:any | any[]):store;
getStore(key:string):Store;
removeStore(键:字符串):存储;
}
}
我得到以下错误:

src/app/app.ts(16,11):错误TS2322:类型“Actions”不可分配给类型“MessageActions”。
类型“Actions”中缺少属性“newMessage”。
src/app/app.ts(35,34):错误TS2345:类型为“typeof MessageStore”的参数不能分配给类型为“Store”的参数。
类型“typeof MessageStore”中缺少属性“register”。

这很公平,因为我知道我可能应该使用接口,但这样我就无法扩展代码中的类。 这里有一个链接,如果你想试试的话

有人能帮我吗?我觉得我错过了一些明显的东西

子类作为参数的Typescript定义

这不是这里的错误。您发布的代码很好:

declare class Actions {
}

declare class Flummox {
  createActions(key: string, store: Actions): Actions;
}

class MessageActions extends Actions {
  newMessage(content: string) {
    return content;
  }
}

class Flux extends Flummox {
  constructor() {
    super();

    this.createActions('messages', MessageActions);
  }
}


如果需要父类,则允许将子类作为参数传递。

如IRC中所述,createStore(store:store)表示createStore采用类型store(或其子类型)的实例,而不是作为store子类型的类型。对于后者,您希望store的类型包含返回store或store的子类型的构造签名。所以

createActions(key: string, actions: Actions, constructorArgs?: any | any[]): Actions;
应该是

createActions(key: string, actions: { new(...args: any[]): Actions }, constructorArgs?: any | any[]): Actions;


将导致问题,因为handleNewMessage中未定义此。this.handleNewMessage返回函数,而不是像其他语言中那样的绑定委托。您需要
this.handleNewMessage.bind(this)
message=>this.handleNewMessage(message)
-后一种形式要求您显式写出所有参数,然而,如果要注册的参数和handleNewMessage的签名不一致,前一个表单不会但会丢失类型检查错误。

哪一行有错误?使用完整的App.ts和到repo的链接更新了帖子,很抱歉,实际上他们的问题是createStore(store:store)表示createStore接受类型Store的实例,而他们希望传入从Store派生的类型。因此,createActions/createStore需要接受具有返回Action/Store而不是Action/Store本身的构造签名的类型。(您的操作恰好工作,因为您的Actions类型为空,所以MessageActions类型可以作为Actions类型的实例。)
createActions<T extends Actions>(key: string, actions: { new(...args: any[]): T }, constructorArgs?: any | any[]): T;
this.register(messageActions.newMessage, this.handleNewMessage);