javascript – 子类的Typescript定义作为参数

我正在尝试为
flummox写一个类型定义,但我不完全理解我应该怎么写它.

要点是我们应该将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;
 }
}

我收到以下错误:

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

这是公平的,因为我知道我应该使用接口,但后来我将无法扩展我的代码中的类.
如果你想尝试,这里是repo的链接

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

最佳答案 正如在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;

要么

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

后者允许您返回传入的相同类型,而不是总是返回Actions,如果需要的话.

createStore()也需要做同样的事情

this.register(messageActions.newMessage, this.handleNewMessage);

会导致问题,因为这将在handleNewMessage中未定义. this.handleNewMessage返回一个函数,而不是像其他语言一样返回绑定的委托.你想要this.handleNewMessage.bind(this)或者message => this.handleNewMessage(消息) – 后一种形式要求你显式地写出所有参数,而前一种形式不会但是如果要注册的参数和handleNewMessage的签名不同意,则会丢失类型检查错误.

点赞