忽略打字稿错误“类型的值不存在属性”


227

在VS2013中,当tsc以代码1退出时,构建停止。VS2012中不是这种情况。

如何在忽略tsc.exe错误的同时运行解决方案?

我收到许多The property 'x' does not exist on value of type 'y'错误,使用JavaScript函数时要忽略。

Answers:


303

我知道这个问题已经结束,但是我发现它正在搜索相同的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

14
您还可以创建一个扩展HTMLElement并具有附加getBBox属性的接口。这样,您仍然可以在其他属性上获得代码完成。
thetallweeks 2014年

getBBox除了强制转换之外,还有什么方法可以强制转换?想找出类型getBBox
Pardeep Jain

FE:如果getBBox是在HTMLElement类型,你可以通过把对象给它var typedElement = <HTMLElement> outerHtmlElement;
michalczukm 2016年

4
真好! var coordinates = (<any>outerElement[0]).getBBox();
bowpunya

1
这实际上没有回答问题:“如何忽略错误”
Petr Peller

121

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

(y as any).x

“优势”在于,强制类型转换是显式的,即使noImplicitAny设置了标志也可以编译。

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

请注意,将变量强制转换为时any,您选择不对该类型进行类型检查。


由于我处于免责声明模式,因此any在您遇到以下情况时,通过与新界面结合使用双重强制转换非常有用

  • 不想更新损坏的打字文件
  • 猴子正在修补

但是,您仍然需要某种形式的键入。

说要修补的一个实例的定义y类型的OrginalDef一个新的属性x类型number

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; server.Server(app); //忽略ts错误!
scape

我在“确保在NodeRequire上找不到属性”中使用了此功能。所以我在NodeRequired和(require as any).ensure属性中声明了我的require变量。希望这可以帮助。
朱尼·布鲁萨斯

61

您还可以使用以下技巧:

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

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

请注意,要再次访问x并不会遇到打字错误,您需要这样写y["x"],而不是y.x。因此,从这个角度来看,其他选择更好。


4
有谁知道为什么这样做,并且与最初将对象声明为相比,这是否有任何潜在的后果或好处:any
mcheah

保留键入内容而不是强制转换为任何内容将具有明显的好处。我想知道为什么不抛出一个警告,但直接访问呢..
Powderham

38

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

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

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

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

declare var y;

这样您就可以拨打任何电话了var y


5
应该/// <reference path="/path/to/jquery.d.ts" />在结尾处带有自动关闭标签
tic

我正在使用VS2015,并且按照教程的角度学习jquery.d.ts,我的项目中没有文件
Dimple

@Dimple npm install -g tsd然后tsd install jquery
Akash

如果要从JavaScript迁移到TypeScript,并且要避免出现TS2304错误,则第二个选项(declare var y)效果很好,因为旧的JavaScript引用了另一个JavaScript文件中的变量。
yesman

谢谢!对我来说,问题出在Jest,const mockPrompt:any = jest.spyOn(step,'prompt');
Mark Robson

18

当打字稿认为,财产的“X”上不存在“Y”,那么你可以随时施放“Y”为“任何”,这将允许您调用任何东西(如“x”)上的“Y”。

理论

(<any>y).x;

真实的例子

我收到此代码的错误“ TS2339:类型'功能'上不存在属性'名称'”:

let name: string = this.constructor.name;

所以我用:

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

1
不适用于super。如果您使用类型扩展类,而作者忘记了一个公共方法,那么您将大为困惑。您必须将其添加到类型定义中,该定义将在下一次npm安装时停止,从而迫使您创建请求请求或以其他方式通知作者,这可能是一件好事,但很痛苦。
科里·阿利克斯

15

Angular2中出现问题,我正在使用本地存储来保存某些内容,但它不允许我这样做。

解决方案:

我有 localStorage.city -> error -> Property 'city' does not exist on type 'Storage'.

解决方法:

localStorage ['city']

(localStorage).city

(localStorage任意).city


第二种选择看起来很酷,但似乎不再起作用。如果在对象前加上<any>- 则可以使用(<any>localStorage).city
jayarjo

我知道这很老了,但您的最佳示例对我有用。
MacD

4

一种快速解决其他问题的方法:

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

不好的做法,但是提供了一种解决方案,而无需关闭无字符串文字


我也这样做,但是某些平台(例如Google Cloud)会发出警告消息,提示ab优于a ['b']。你知道为什么吗
乔纳森

1
不确定,但是您可以例如在tslint.json中更改选项,使其更喜欢ab
danday74 '19

3

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

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

通常,这会引发错误,指出“ type上不存在someProp”。有了注释,该错误就消失了。

这将阻止编译时引发的任何错误,并且还应避免IDE向您抱怨。


0

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


0

我可以使用类似这样的文字来解决这个问题:

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的键并进行编译的唯一方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.