键入声明可消除对象或函数的歧义

时间:2019-06-10 19:43:53

标签: typescript

我正在尝试使Dockerode run typingsthe implementation匹配。问题是,无论我用什么TypeScript调用run,返回值都为Promise

我认为问题在于TypeScript正在将functionObject匹配,并且不能消除类型声明中run的重载。尽管我承认我对为什么有些困惑。

I've made a small example in a TypeScript Playground that I think exemplifies the error.

// index.d.ts
declare class EventEmitter {
  emit(): void;
}

type RunCallback = (error: any, result: string | null, value: number) => void;

declare class Foo {
  run(one: string, two: string[], option1: Object, option2: Object): Promise<number>;
  run(one: string, two: string[], option1: Object, callback: RunCallback): EventEmitter;
}

declare class Bar {
  run(one: string, two: string[], option1: Object, callback: RunCallback): EventEmitter;
}

// worker.ts
function callback(a: Error, data: string | null, container: number) {}

const broken: EventEmitter = new Foo().run('', [''], {}, callback);
const works: EventEmitter = new Bar().run('', [''], {}, callback);

请注意,broken在操场上无法编译,因为broken是以Promise而不是EventEmitter的形式返回的。有建议吗?

2 个答案:

答案 0 :(得分:2)

一切都是Object中的Javascript,包括函数。这就是函数与对象重载匹配的原因。

重载顺序很重要,将函数重载放在首位将匹配相应的重载:

// index.d.ts
declare class EventEmitter { emit(): void; }

type RunCallback = (error: any, result: string | null, value: number) => void;

declare class Foo {
  run(one: string, two: string[], option1: Object, callback: RunCallback): EventEmitter;
  run(one: string, two: string[], option1: Object, option2: Object): Promise<number>;
}

// worker.ts
function callback(a: Error, data: string | null, container: number) { }

const c1: EventEmitter = new Foo().run('', [''], {}, callback);
const c2: Promise<number> = new Foo().run('', [''], {}, {}); 

答案 1 :(得分:0)

我不确定将RunCallback分配给Object的确切原因。也许是由于JavaScript函数的性质(请参见this

但是,将option1option2替换为其他内容(Record)似乎可以达到您想要的结果。无论如何,我认为这更符合您的需求。

Here's a working example