【问题标题】:Ignore Typescript Errors "property does not exist on value of type"忽略 Typescript 错误“类型的值不存在属性”
【发布时间】:2013-08-07 15:34:52
【问题描述】:

在 VS2013 中,当 tsc 以代码 1 退出时,构建停止。在 VS2012 中情况并非如此。

如何在忽略 tsc.exe 错误的情况下运行我的解决方案?

我收到很多 The property 'x' does not exist on value of type 'y' 错误,我想在使用 javascript 函数时忽略这些错误。

【问题讨论】:

    标签: javascript typescript visual-studio-2013


    【解决方案1】:

    有几种方法可以解决这个问题。如果该对象与某个外部库相关,最好的解决方案是找到该库的实际定义文件(大存储库here)并引用它,例如:

    /// <reference path="/path/to/jquery.d.ts" >
    

    当然,这在很多情况下并不适用。

    如果您想“覆盖”类型系统,请尝试以下操作:

    declare var y;
    

    这将使您可以在var y 上拨打任何您想要的电话。

    【讨论】:

    • 应该是/// &lt;reference path="/path/to/jquery.d.ts" /&gt;,末尾有自结束标签
    • 我正在使用 VS2015 并遵循 this 角度教程我的项目中没有 jquery.d.ts 文件
    • @Dimple npm install -g tsd 然后tsd install jquery
    • 第二个选项(declare var y)如果您正在从 JavaScript 迁移到 TypeScript,并且想要避免错误 TS2304,因为您的旧 JavaScript 正在引用另一个 JavaScript 文件中的变量。
    • 谢谢!对我来说,问题在于 Jest, const mockPrompt: any = jest.spyOn(step, 'prompt');
    【解决方案2】:

    我知道这个问题已经结束,但我发现它正在搜索相同的 TypeScriptException,也许其他人在搜索这个问题时遇到了这个问题。

    问题在于缺少 TypeScript 输入:

    var coordinates = outerElement[0].getBBox();
    

    抛出The property 'getBBox' does not exist on value of type 'HTMLElement'.


    最简单的方法是将变量显式键入为 `any`
    var outerHtmlElement: any = outerElement[0];
    var coordinates = outerHtmlElement.getBBox();
    

    编辑,2016 年底

    从 TypeScript 1.6 开始,首选的转换运算符是 as,因此这些行可以压缩为:

    let coordinates = (outerElement[0] as any).getBBox();


    其他解决方案

    当然,如果你想把事情做对,这有时是一种矫枉过正,你可以:

    1. 创建自己的接口,简单地扩展HTMLElement
    2. 引入自己的类型,扩展HTMLElement

    【讨论】:

    • 您还可以创建一个扩展HTMLElement 并具有附加getBBox 属性的接口。这样您仍然可以在其他属性上完成代码。
    • 而不是投射到任何 getBBox 是否有任何方法可以正确投射?想知道getBBox的类型?
    • 不错! var coordinates = (&lt;any&gt;outerElement[0]).getBBox();
    • 这实际上并没有回答问题:“如何忽略错误”
    • as any 技巧适用于我的场景。感谢您的提示。
    【解决方案3】:

    您还可以使用以下技巧:

    y.x = "some custom property"//gives typescript error

    y["x"] = "some custom property"//no errors

    请注意,要访问 x 并且不会再次出现打字错误,您需要像 y["x"] 那样编写它,而不是 y.x。所以从这个角度来看,其他选择更好。

    【讨论】:

    • 有谁知道这为什么有效,以及这是否比最初将对象声明为:any 有任何潜在的后果或好处?
    • 它的明显好处是保留类型,而不是强制转换为任何类型。我想知道为什么这不会引发警告但直接访问会..
    【解决方案4】:

    在我的特定项目中,我无法让它工作,并使用了declare var $;。 不是一个干净/推荐的解决方案,它不能识别 JQuery 变量,但在使用之后我没有任何错误(并且必须让我的自动构建成功)。

    【讨论】:

      【解决方案5】:

      快速而肮脏的解决方案是显式转换为any

      (y as any).x
      

      “优点”是,演员表是明确的,即使设置了noImplicitAny 标志,它也会编译。

      正确的解决方案是更新类型定义文件。

      请注意,当您将变量强制转换为 any 时,您选择退出对该变量的类型检查。


      由于我处于免责声明模式,通过any 结合新界面进行双重投射,在以下情况下很有用

      • 您不想更新损坏的类型文件
      • 和/或你是猴子补丁

      然而,你仍然需要某种形式的打字。

      假设您想使用 number 类型的新属性 x 来修补 y 类型 OrginalDef 的实例的定义:

      const y: OriginalDef = ...
      
      interface DefWithNewProperties extends OriginalDef {
          x: number
      }
      
      const patched = y as any as DefWithNewProperties
      
      patched.x = ....   //will compile
      

      【讨论】:

      • 感谢帮助:import http = require('http'); var server = http as any;服务器。服务器(应用程序); //忽略ts错误!
      • 我在“确保在 NodeRequire 上找不到属性”中使用了它。所以我在 NodeRequired 和 (require as any).ensure 上声明了我的 require 变量。希望这会有所帮助。
      【解决方案6】:

      在 Angular2 中遇到问题,我正在使用本地存储来保存一些东西,但它不让我这样做。

      解决方案:

      我有localStorage.city -&gt; error -&gt; Property 'city' does not exist on type 'Storage'.

      如何解决:

      localStorage['city']

      (localStorage).city

      (localStorage as any).city

      【讨论】:

      • 第二个选项看起来很酷,但似乎不再起作用了。如果您使用 &lt;any&gt; - (&lt;any&gt;localStorage).city 为对象添加前缀,则可以使用。
      • 我知道这是旧的,但你的顶级例子对我有用.. 干得好。
      【解决方案7】:

      当 TypeScript 认为 "y" 上不存在属性 "x" 时,您始终可以将“y”转换为“any”,这将允许您在“y”上调用任何东西(如“x”)。

      理论

      (<any>y).x;
      

      现实世界的例子

      我收到此代码的错误“TS2339:类型‘函数’上不存在属性‘名称’”:

      let name: string = this.constructor.name;
      

      所以我修复了它:

      let name: string = (<any>this).constructor.name;
      

      【讨论】:

      • 不适用于超级。如果您使用类型扩展一个类,而作者忘记了一个公共方法,那么您就完蛋了。您必须将其添加到类型定义中,该定义会在下一次 npm 安装时停止,从而迫使您创建拉取请求或以其他方式通知作者,这可能是一件好事,但也很痛苦。
      【解决方案8】:

      我能够在打字稿中使用类似的东西来解决这个问题:

      let x = [ //data inside array ];
      let y = new Map<any, any>();
      for (var i=0; i<x.length; i++) {
          y.set(x[i], //value for this key here);
      }
      

      这似乎是我可以使用 X 中的值作为映射 Y 的键并进行编译的唯一方法。

      【讨论】:

        【解决方案9】:

        在没有其他方法的情况下快速修复:

        const a.b = 5 // error
        
        const a['b'] = 5 // error if ts-lint rule no-string-literal is enabled
        
        const B = 'b'
        const a[B] = 5 // always works
        

        不是很好的做法,但提供了无需关闭 no-string-literal 的解决方案

        【讨论】:

        • 我也这样做,但某些平台(如 Google Cloud)会发出警告消息,提示 a.b 优于 a['b']。你知道这是为什么吗?
        • 不确定,但您可以,例如在 tslint.json 中更改选项,使其更喜欢 a.b
        【解决方案10】:

        我知道现在是 2020 年,但我找不到满足问题“忽略”部分的答案。事实证明,您可以使用指令告诉 TSLint 这样做;

        // @ts-ignore
        this.x = this.x.filter(x => x.someProp !== false);
        

        通常这会引发错误,指出“someProp 在类型上不存在”。有了评论,这个错误就消失了。

        这将阻止编译时抛出的任何错误,并且还应该阻止您的 IDE 向您抱怨。

        【讨论】:

          猜你喜欢
          • 2020-04-25
          • 1970-01-01
          • 2018-05-16
          • 2020-10-19
          • 2023-02-21
          • 2019-04-12
          • 2020-07-09
          • 2019-10-20
          • 2021-09-26
          相关资源
          最近更新 更多