TypeScript:类型“{}”上不存在属性

159

我正在使用完全打了补丁的Visual Studio 2013。我试图使用JQuery、JQueryUI和JSRender,也在尝试使用TypeScript。在ts文件中,我遇到了以下错误:

"Property 'fadeDiv' does not exist on type '{}'."

我认为我已经为TypeScript引用了正确的JQuery、JQueryUI和JSRender,但从我所读的内容来看,这似乎是一个d.ts问题。

JavaScript中没有出现任何错误,但我不想让Visual Studio说有错误,如果可能的话。在JavaScript中两次提到fadeDiv时,都有红色线条,而且两个错误显示的都是与上面相同的内容。

/// <reference path="../scripts/typings/jquery/jquery.d.ts" />
/// <reference path="../scripts/typings/jqueryui/jqueryui.d.ts" />
/// <reference path="typings/jsrender/jsrender.d.ts" />

var SUCSS = {};

$(document).ready(function () {
   SUCSS.fadeDiv();
});

SUCSS.fadeDiv = function () {
var mFadeText: number;
$(function () {
    var mFade = "FadeText";
    //This part actually retrieves the info for the fadediv
    $.ajax({
        type: "POST",
        //url: "/js/General.aspx/_FadeDiv1",
        url: "/js/sucss/General.aspx/_FadeDivList",
        //data: "{'iInput':" + JSON.stringify(jInput) + "}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        error: function (xhr, status, error) {
            // Show the error
            //alert(xhr.responseText);
        },
        success: function (msg) {
            mFadeText = msg.d.Fade;
            // Replace the div's content with the page method's return.
            if (msg.d.FadeType == 0) {//FadeDivType = List
                var template = $.templates("#theTmpl");
                var htmlOutput = template.render(msg.d);
                $("[id$=lblFadeDiv]").html(htmlOutput);
            }
            else {//FadeDivType = String
                $("[id$=lblFadeDiv]").html(msg.d.FadeDivString);
            }
        },
        complete: function () {
            if (mFadeText == 0) {
                $("[id$=lblFadeDiv]").fadeIn('slow').delay(5000).fadeOut('slow');
            }
        }
    });
});

对于那些可能稍后阅读此内容的人,SUCSS是命名空间。在typescript中,似乎我想做的是这样的。

$(document).ready(function () {
    SUCSS.fadeDiv();
});
module SUCSS {
    export function fadeDiv () {};
};

因此,通过使用export,该函数已被公开,并且我可以调用SUCSS.fadeDiv通过调用SUCSS.fadeDiv();在页面加载时运行。我希望这会有所帮助。


1
你似乎缺少至少一个闭合的 } 大括号,也许还有其他代码。 - mk.
2
你需要将这段代码简化成一个自包含的示例,以便其他人可以重现这个问题。目前为止,你使用了大量没有定义的变量,因此我们只能猜测它们的类型。 - Ryan Cavanaugh
9个回答

175

您可以将any类型分配给对象:

let bar: any = {};
bar.foo = "foobar"; 

8
最好使用任意语法: let bar = {} as any; bar.foo = "foobar"; - eKelvin
16
我更喜欢使用 let bar: any = {}; 这个语句。 - Maor Refaeli

78

使用数组符号访问字段,以避免在单个字段上进行严格类型检查:

data['propertyName']; //will work even if data has not declared propertyName

另一种方法是将变量转换为非/可选状态以进行单次访问:


(<any>data).propertyName;//access propertyName like if data has no type

第一个更短,第二个更明确关于类型(不)转换


你也可以完全禁用所有变量字段的类型检查:

let untypedVariable:any= <any>{}; //disable type checking while declaring the variable
untypedVariable.propertyName = anyValue; //any field in untypedVariable is assignable and readable without type checking

注意:这比仅为单个字段访问避免类型检查更加危险,因为所有连续访问的所有字段都是无类型的。

9
如果我们只是用这种hack方法来规避TypeScript,使用TypeScript的意义在哪里? - Damien Roche
11
Typescript的类型检查并不是严格和强制性的,它更像是一个强烈的推荐,你可以随时使用< any >来绕过它。通常情况下,你必须这样做,因为在Web中你需要与JavaScript库、无类型的JSON API和动态生成的对象进行交互。在这种情况下,你需要使用类似反射的功能,这也是Java所拥有的功能。因此,无论是使用Java还是C#,都需要使用这种特殊情况下的功能。 - Luca C.

26
let propertyName= data['propertyName'];

1
那是唯一一个真正解决了我的编译问题的方法。即使像这样声明:{ section: { year: any }[] },也会出现错误:在类型“{ year: Number; }[]”上不存在属性“year”。 - Paweł Stolka

18

当你在TypeScript中编写以下代码时:

var SUCSS = {};

SUCSS 的类型是从赋值中推断出来的(即它是一个空对象类型)。

几行代码后,您继续向此类型添加属性:

SUCSS.fadeDiv = //...

编译器提醒您,在SUCSS对象上没有名为fadeDiv的属性(此类警告通常有助于捕获拼写错误)。

您可以通过指定SUCSS的类型来解决这个问题(尽管这会阻止您分配{},因为它不满足您想要的类型):

var SUCSS : {fadeDiv: () => void;};

或者在一开始就给变量赋上完整的值,让 TypeScript 推断类型:

var SUCSS = {
    fadeDiv: function () {
        // Simplified version
        alert('Called my func');
    }
};

12

我建议进行如下更改。

let propertyName =  {} as any;

1
欢迎来到SO,Kovacs!请编辑您的答案,以便包含一个与所提问相关的简短介绍段落。除此之外,简要解释一下为什么您的答案可以解决这个问题会更好。 - B--rian
1
我非常喜欢这个解决方案,比其他提到的方案都要好。 - wvdz

6

1
myFunction(
        contextParamers : {
            param1: any,
            param2: string
            param3: string          
        }){
          contextParamers.param1 = contextParamers.param1+ 'canChange';
          //contextParamers.param4 = "CannotChange";
          var contextParamers2 : any = contextParamers;// lost the typescript on the new object of type any
          contextParamers2.param4 =  'canChange';
          return contextParamers2;
      }

1

var SUCSS = {}; 隐式定义了 SUCSS 的类型为一个没有属性的对象。如果您想允许它拥有可选的属性,那么您应该 显式 定义其类型。

type SUCESSType = {
    fadeDiv?: () => void;
};

const SUCSS: SUCESSType = {};

话虽如此,fadeDiv的值紧随其后就被定义了,因此没有必要将该属性设置为可选的(这将需要在调用它之前测试它是否存在)。

您可以在创建对象时直接分配函数。

const SUCSS = {
    fadeDiv = function () { /* function body */ }
};

0
在文件顶部附近,您需要写入var fadeDiv = ...而不是fadeDiv = ...,以便实际声明变量。
错误““Property 'fadeDiv' does not exist on type '{}'.”似乎触发了您在示例中未发布的一行(该片段中没有任何访问fadeDiv属性的地方)。

非常抱歉,这是完整的代码...示例中只是遗漏了一个命名空间,但错误是相同的。错误发生在文档加载的SUCSS.fadeDiv()函数上,还有在SUCSS.fadeDiv = function(){}行上。 - jvcoach23
这并不是什么改进,因为您也没有发布“SUCSS”的定义... - Ryan Cavanaugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接