【问题标题】:Typescript typeguard error in class constructor类构造函数中的打字稿类型保护错误
【发布时间】:2016-08-01 19:46:45
【问题描述】:

我有一个类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())相关的错误,即类型保护不起作用。

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

【问题讨论】:

  • 您的代码没有错误,即使当我添加console.log(v.slice(0, 3)) 时它是一个字符串,我也没有错误。请提供导致错误的代码。
  • @NitzanTomer 添加了一些额外的代码,现在它给出了我提到的一些错误。

标签: typescript


【解决方案1】:

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

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

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

在“if”语句的真正分支语句中,a 的类型 变量或参数被“if”中的类型保护缩小 条件为真,前提是“if”语句的任何部分都不包含 对变量或参数的赋值

.

【讨论】:

  • 这并没有解决 (v instanceof BigNumber) 块中的错误。类型 'string | 上不存在属性's'号码 | BigNumber 错误。我还在数字块中添加了一些代码,导致错误而不重新分配。
  • 删除“字符串”块中的重新分配后,我在任何块中都没有收到任何错误
  • 你是对的,我在数字块中进行了另一个重新分配(问题中未显示),删除它后,一切都在编译没有错误。有趣的是,一个块中的重新分配会导致所有三个块中的类型错误。
【解决方案2】:

如果你确定类型(在这种情况下你是因为类型检查),你可以通过在抱怨的变量上使用 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
}

...

【讨论】:

    猜你喜欢
    • 2017-01-29
    • 2017-03-03
    • 1970-01-01
    • 2019-07-05
    • 2021-03-25
    • 2019-04-13
    • 2020-05-11
    • 2017-05-18
    相关资源
    最近更新 更多