Javascript 打字稿 - TypeError myclass.myFunction 不是函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34031448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:49:30  来源:igfitidea点击:

Typescript - TypeError myclass.myFunction is not a function

javascriptfunctiontypescriptundefined

提问by FrW

I'm facing an issue with the following code.

我正面临以下代码的问题。

What it basically should do. It should load and parse a given JSON file. And in the RequestListender it should show the IDand the string Hellowhich is returned by the ToString()method in Product.ts. Where the tProduct.Idis shows up correctly, the tProduct.ToString()method fails with the error stated below.

它基本上应该做什么。它应该加载和解析给定的 JSON 文件。在 RequestListender 中,它应该显示Product.ts 中的方法返回ID的字符串。在正确显示的地方,该方法失败并出现以下错误。HelloToString()tProduct.IdtProduct.ToString()

Thanks a lot in advance.

非常感谢。

Error message:

错误信息:

TypeError: tProduct.ToString is not a function. 
 (In 'tProduct.ToString()', 'tProduct.ToString' is undefined)

File: Test.ts

文件:Test.ts

var currentProduct = null as pvis.Product;

function runTest(path) {
    var request = new XMLHttpRequest();
    request.onload = loadRequestListener;
    request.open("get", path, true);
    request.send();
}

function loadRequestListener () {
    var tProduct : pvis.Product = JSON.parse(this.responseText);
    if (tProduct.Id) {
        currentProduct = tProduct;
        alert('loaded with Id: ' + tProduct.Id );   
        alert('loaded with Content: ' + tProduct.ToString() );  
    }
    else {
        alert('product failed to load');
    }

}

File Product.ts

文件 Product.ts

module pvis {
    export class Product {

        Id: string;

        ToString():string {
            return 'Hello';
        }
    }
}

The HTML part:

HTML部分:

<body onload="runTest('assets/products/json/A379N.json')">

The compiled Javascript:

编译后的 Javascript:

var pvis;
(function (pvis) {
    var Product = (function () {
        function Product() {
        }
        Product.prototype.ToString = function () {
            return 'Hello';
        };
        return Product;
    })();
    pvis.Product = Product;
})(pvis || (pvis = {}));
var currentProduct = null;
function runTest(path) {
    var request = new XMLHttpRequest();
    request.onload = loadRequestListener;
    request.open("get", path, true);
    request.send();
}
function loadRequestListener() {
    var tProduct = JSON.parse(this.responseText);
    if (tProduct.Id) {
        currentProduct = tProduct;
        alert('loaded with Id: ' + tProduct.Id);
        alert('loaded with Content: ' + tProduct.ToString());
    }
    else {
        alert('product failed to load');
    }
}

The tsconfig.json (I'm not sure if it is relevant):

tsconfig.json(我不确定它是否相关):

{
    "compilerOptions": {
        "target": "ES5",
        "removeComments": true,
        "preserveConstEnums": true,
        "out": "js/main.js",
        "sourceMap": true
    },
    "files": [
       "src/Test.ts"
    ]
}

采纳答案by Nypan

The line:

线路:

var tProduct : pvis.Product = JSON.parse(this.responseText);

is wrong. The reason it compiles is only due to JSON.parsereturning any.

是错的。它编译的原因只是由于JSON.parse返回any.

to use the class Productyou have to create an instance of it somehow. JSON parse will not do this, it will simply return an object with the parsed JSON in it, it will not be an instance of the pvis.Productclass.

要使用该类,Product您必须以某种方式创建它的实例。JSON 解析不会这样做,它只会返回一个包含解析 JSON 的对象,它不会是pvis.Product类的实例。

If what you want to do is type the JSON result you can do that with an interface. For example if you have a JSON object on the form:

如果您想要做的是输入 JSON 结果,您可以使用接口来完成。例如,如果表单上有一个 JSON 对象:

{
    id: "some value",
    name: "some name",
    count: 4
}

You can type that with the interface:

您可以在界面中输入:

interface myInterface {
    id: string;
    name: string;
    count: number;
}

And use it like so:

并像这样使用它:

var myParsedAndTypedJson: myInterface = JSON.parse("....");

An object created like that will never have methods however, if you want that functionality you have to pass this information in to a class that can use it some how, for example;

像这样创建的对象永远不会有方法,但是,如果您想要该功能,则必须将此信息传递给可以以某种方式使用它的类,例如;

class myClass implements myInterface {

    get id(): string { return this.initData.id; }
    get name(): string { return this.initData.name; }
    get count(): number { return this.initData.count; }

    constructor(private initData: myInterface) {

    }

    public ToString() {
        return this.id + ' ' + this.name + ' ' + this.count;
    }
}

Working example of this can be found here.

可以在此处找到工作示例。

You might want to look up how to work with typescript interfaces and JSON to learn a bit more about how this works.

您可能想查看如何使用 typescript 接口和 JSON 以了解有关其工作原理的更多信息。

回答by Dustin Hodges

I'm not familiar with TypeScript, but looking at the compiled JavaScript, I notice that tProduct is just a POJO, not an instance of the Product class (i.e. tProduct instanceof Product === false).

我不熟悉 TypeScript,但是查看编译后的 JavaScript,我注意到 tProduct 只是一个 POJO,而不是 Product 类(即tProduct instanceof Product === false)的实例。

The reason Id doesn't error is because JSON.parse returns an object with an Id property.

Id 没有错误的原因是因为 JSON.parse 返回一个带有 Id 属性的对象。

To see how to deserialize to a TypeScript type, you can check the following answer: How do I initialize a typescript object with a JSON object

要了解如何反序列化为 TypeScript 类型,您可以查看以下答案:How do I initialize a typescript object with a JSON object