如何在TypeScript中显式定义通用返回类的返回类型?

时间:2018-12-14 18:49:11

标签: typescript generics

我有这样的代码:

import * as events from 'events' // Node.js events module

// my own version of EventEmitter with better typing
interface IEventEmitter<EventTypes> { /* ... */ }

// eslint-disable-next-line typescript/explicit-function-return-type
export function EventEmitter<EventTypes>() {
  // merge the IEventEmitter interface and EventEmitter as IEventEmitter
  // implementation into one.
  // XXX Is there a better way?
  return class NewEventEmitter
    extends ((events.EventEmitter as unknown) as IEventEmitter<EventTypes>)
    implements IEventEmitter<EventTypes> {}
}

如您所见,我禁用了eslint规则,以便它不会抱怨我没有指定返回类型,并且让我推断出返回类型。

但是,我如何 编写该返回类型?

编辑:这是一个playground example,表明@KarolMajewski的答案对我不起作用。它说Cannot find name 'NewEventEmitter'. Did you mean 'NodeEventEmitter'?

编辑2:@KarolMajewski的答案确实有效。为了使其正常工作,必须将类分配给局部变量。这是playground example

2 个答案:

答案 0 :(得分:1)

在编写显式返回类型和让TypeScript推断其类型之间,还有第三种方法:

import * as events from 'events';

interface IEventEmitter<EventTypes> { /* ... */ }

export function EventEmitter<EventTypes>(): typeof MyClass {
  const MyClass = class extends events.EventEmitter implements IEventEmitter<EventTypes> {};

  return MyClass;
}

尽管有些技巧,但它需要所谓的不必要的局部变量。在这种情况下,此变量(MyClass)仅用于读取类型。

答案 1 :(得分:0)

声明返回类型为IEventEmitter<EventTypes>

function makeEventEmitterClass<EventTypes>(): IEventEmitter<EventTypes> {
  // merge the IEventEmitter interface and EventEmitter as IEventEmitter
  // implementation into one.
  return class NewEventEmitter
    extends ((NodeEventEmitter as unknown) as IEventEmitter<EventTypes>)
    implements IEventEmitter<EventTypes> {}
}