Typescript - 类型错误:myclass.myFunction不是一个函数。

49

我在以下代码中遇到了一些问题。

它基本上应该做什么。它应该加载和解析给定的JSON文件。并且在RequestListener中,它应该显示IDProduct.tsToString()方法返回的字符串Hello。当tProduct.Id正确显示时,tProduct.ToString()方法会失败,并显示下面所述的错误。

提前感谢您的大力协助。

错误信息:

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

文件: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');
    }

}

产品文件Product.ts

module pvis {
    export class Product {

        Id: string;

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

HTML部分:

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

编译后的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');
    }
}

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

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

40

这行代码:

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

是错误的。它编译成功的原因只是因为 JSON.parse 返回了 any 类型。

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

如果您想对JSON结果进行类型标注,可以使用接口。例如,如果您有一个 JSON 对象形如:

{
    id: "some value",
    name: "some name",
    count: 4
}
你可以用界面输入那个:
interface myInterface {
    id: string;
    name: string;
    count: number;
}

然后像这样使用它:

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

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

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;
    }
}

可以在这里找到此示例的工作代码。

您可能想要查阅有关如何使用 TypeScript 接口和 JSON 的资料,以了解更多相关信息。


接口方法是我的首选方案,就像你发布的一样。我只是从示例中删除了它,以使其更短。 - frank
抱歉...我在这里还很新(按下回车键),所以这是完整的答案:接口方法是我的第一选择。几乎就像你发布的那样。我只是从示例中删除了它,以使其更短,因为接口不是问题的一部分。正如你和@Dustin-Hodges所说,问题出在JSON.parse上,它没有创建实例。而我一直在假设它会创建实例。感谢您的支持并给我正确的方向。 - frank
没问题,我更新了我的回答以修复代码中的一些错误,并提供了一个可运行的示例。很高兴能帮忙! - Nypan
谢谢。现在它可以工作了。我只需要做一个小改变:将这一行var myParsedAndTypedJson: myInterface = JSON.parse("....");改为(然后它就可以很好地工作了):var myParsedAndTypedJson: myInterface = new myClass(JSON.parse("....")); - frank
1
谢谢!这帮助我意识到我的用户对象没有作为其类的实例传递。它被传递为类型为User的普通JS对象。这就是为什么它缺少真正的用户对象所有方法...这有点让人沮丧,关于TypeScript呢。 - Sam Malayek

5

我遇到了这个错误,原因是我的文件中存在循环依赖。 我将这两个函数放在同一个文件中,问题得到解决。


fileA.ts

import { foo } from "./fileB"

export function bar() { ... }

foo();

fileB.ts

import { bar } from "./fileA"

export function foo() { ... }

bar();

这会产生以下结果:

TypeError: fileA_1.foo 不是一个函数


那么解决方案是什么? - Diego
将它们放在同一个文件中,或重新考虑你的文件结构。 - maxpaj

1
我不熟悉TypeScript,但查看编译后的JavaScript代码后,我注意到tProduct只是一个POJO,而不是Product类的实例(即tProduct instanceof Product === false)。
Id不报错的原因是因为JSON.parse返回一个具有Id属性的对象。
要了解如何反序列化为TypeScript类型,您可以查看以下答案:如何使用JSON对象初始化TypeScript对象

1
我之所以出现了这个错误,是因为对象使用的表示法是<ClassName>{}。当我将其更改为new ClassName()后,问题得到解决。

0
你可以创建一个带有接口方法的类。
interface IMyInterface() {
}

class MyInterfaceMethods () {
     static MyMethod(IMyInterface data) {
    
     }
}

可能有一种替代方案 - Mixins。


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