类构造函数中的Typescript typeguard错误

时间:2016-08-01 08:49:12

标签: typescript

我有一个类BigNumber,其构造函数采用初始化参数,可以是字符串,数字或BigNumber。在给定参数类型的情况下,构造函数将使用适当的策略初始化BigNumber的实例:

export class BigNumber
{
     private static isDecimal = /^(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;

     public d : number[];
     public e : number;
     public s : number;

     constructor(v : string | number | BigNumber)
     {
         let e, i, t,
             x = this;

         if (v instanceof BigNumber)
         {
              // code dependent of v being a BigNumber
              x.s = v.s;
              x.e = v.e;
              x.d = v.d.slice();
              return;
         }
         else if (typeof v === 'number')
         {
             // code dependent of v being a number

             if (v === 0)
             {
                x.s = (1 / v < 0) ? -1 : 1;
                x.e = 0;
                x.d = [0];
                return;
             }

             // Other stuff
         }
         else if(typeof v === 'string')
         {
             // code dependent of v being a string
             if (v.charCodeAt(0) === 45)
             {
                 v = v.slice(1);
                 x.s = -1;
             }
             else
             {
                 x.s = 1;
             }

             // Other stuff
         }
         else
         {
             // throw error
         }
     }
}

问题是打字稿引发了许多与在字符串部分中进行分配或调用slice()等函数有关的错误,即类型控制不起作用。

这些可以通过每个操作的显式强制转换来修复,但我的印象是typescript编译器能够推断出instanceOf或typeof块中的类型。我哪里出错?

2 个答案:

答案 0 :(得分:1)

主要问题是您将v参数的值重新分配给v = v.slice(1);

使用另一个变量修复了tsc编译器错误:let vv; vv = v.slice(1);

根据Type Guards specification,不允许对变量或参数赋值:

  

在&#39; if&#39;的真正分支声明中声明,一种类型   变量或参数由&#39;中的类型保护器缩小。   当条件为真时,不提供“如果&#39;声明包含   赋值给变量或参数

答案 1 :(得分:0)

如果你确定类型(在这种情况下你是因为类型检查)你可以通过对变量抱怨使用 type assertion 将提示传递给TypeScript编译器:

...

else if( v === "string")
{
    // code dependent of v being a string
    if ((<string>v).charCodeAt(0) === 45)
    {
        v = (<string>v).slice(1);
        x.s = -1;
    }
    else
    {
        x.s = 1;
    }

    // Other stuff
}

...