打字稿,准确地反映类方法的行为

打字稿,准确地反映类方法的行为

问题描述:

我有几个接口和类有一个可选选项对象:打字稿,准确地反映类方法的行为

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如任一stringasObject

var AObject = new A().go({ returnAs: 'object|string' }); 

我不是100%肯定它可能在打字稿中,在那种情况下,我很乐意提供一个建议。

+0

不确定,您在做什么。你为什么要同时拥有'asObject'和'string'对象?您可以使用'else'而不是2种方法,请参阅[示例](http://goo.gl/motrsx) –

最简单的方法是声明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

嗨,谢谢,我非常喜欢这些示例和描述性解释。 –