我有几个接口和一个带有可选选项对象的类:
interface asObject { a: number, b: number }
interface options { returnAs: string; }
interface IA {
go(): string;
go(o: options): string | asObject;
}
class A implements IA {
public go(o?: options): string | asObject {
if(o&& o.returnAs && typeof o.returnAs === 'string') {
switch(o.returnAs) {
case 'object':
return { a: 5, b: 7 };
default:
return 'string';
}
}
}
}
我得到的错误:“类A
错误地实现了接口IA
”。
如果我尝试重载方法:
...
public go(): string;
// Notice the parameter is no longer optional, ? removed.
public go(o: options): string | asObject { /* implementation as above */ }
...
现在我得到:“重载签名与功能实现不兼容”。
我知道我可以删除IA
界面上的重载签名并删除A
类上的重载方法:
// Interface IA, notice the parameter is now optional, ? added.
go(o?: options): string | asObject;
// Class A
public go(o?: options): string | asObject { /* implementation as above */ }
让我解释一下:
A
类有一个名为go
的方法,如果go
没有提供选项对象,它将返回一个字符串,但如果用户提供了一个选项对象,返回值取决于returnAs
字段,表示字符串或对象。
我的问题:
我认为我提供的解决方案并不能准确表示go
方法的行为。
有没有办法保留准确的行为以便使用打字稿而不会像我上面描述的前2次尝试那样出错?
当我说出准确的行为时,我的意思是:
我正在寻找一种方法,其中打字稿能够将AObject
类型推断为string
:
var AObject = new A().go();
它可以将AObject
推断为string
或asObject
:
var AObject = new A().go({ returnAs: 'object|string' });
我不是百分之百确定在打字稿中是否可行,在这种情况下我会很高兴提出建议。
答案 0 :(得分:3)
最简单的方法是将A.go
结果声明为any
:
public go(o?: options): any {
或声明功能界面:
interface asObject { a: number, b: number }
interface options { returnAs: string; }
interface IGoFunction {
(): string;
(o: options): string | asObject;
}
interface IA {
go: IGoFunction;
}
class A implements IA {
go = <IGoFunction>function (o?: options): string | asObject {
if (o && o.returnAs && typeof o.returnAs === 'string') {
switch (o.returnAs) {
case 'object':
return { a: 5, b: 7 };
default:
return 'string';
}
}
}
}
实际上你甚至不需要声明命名接口:
class A {
go = <{
(): string;
(o: options): string | asObject;
}>function (o?: options): string | asObject {
...
缺点是该函数已添加到A
的每个实例中,但您可以将其显式添加到原型中:
class A {
go: {
(): string;
(o: options): string | asObject;
};
}
A.prototype.go = function (o?: options): any {
...