打字稿,准确地反映类方法的行为
问题描述:
我有几个接口和类有一个可选选项对象:打字稿,准确地反映类方法的行为
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
方法的行为。
有没有办法保持准确的行为,为了打字稿的用法,没有得到错误,就像我上面描述的前两次尝试一样?
当我说准确的行为我的意思是:
我正在寻找一种方式,其中打字稿就能推断AObject
类型string
:
var AObject = new A().go();
它就能推断AObject
如任一string
或asObject
:
var AObject = new A().go({ returnAs: 'object|string' });
我不是100%肯定它可能在打字稿中,在那种情况下,我很乐意提供一个建议。
答
最简单的方法是声明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 {
...
+0
嗨,谢谢,我非常喜欢这些示例和描述性解释。 –
不确定,您在做什么。你为什么要同时拥有'asObject'和'string'对象?您可以使用'else'而不是2种方法,请参阅[示例](http://goo.gl/motrsx) –