web-dev-qa-db-fra.com

Typescript - TypeError myclass.myFunction n'est pas une fonction

Je suis confronté à un problème avec le code suivant. 

Qu'est-ce qu'il devrait fondamentalement faire. Il convient de charger et d’analyser un fichier JSON donné. Et dans RequestListender, il devrait afficher ID et la chaîne Hello qui est renvoyée par la méthode ToString() dans Product.ts . Lorsque le tProduct.Id s'affiche correctement, la méthode tProduct.ToString() échoue avec l'erreur indiquée ci-dessous.

Merci beaucoup d'avance.

Message d'erreur:

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

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

}

Fichier Product.ts

module pvis {
    export class Product {

        Id: string;

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

La partie HTML:

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

Le Javascript compilé:

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

Le tsconfig.json (je ne sais pas s'il est pertinent):  

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

La ligne:

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

est faux. La raison pour laquelle il compile est uniquement due à JSON.parse retournant any.

pour utiliser la classe Product, vous devez en créer une instance. L'analyse JSON ne le fera pas, elle renverra simplement un objet contenant le JSON analysé, ce ne sera pas une instance de la classe pvis.Product.

Si vous voulez taper le résultat JSON, vous pouvez le faire avec une interface. Par exemple, si vous avez un objet JSON sur le formulaire:

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

Vous pouvez taper cela avec l'interface: 

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

Et utilisez-le comme suit:

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

Un objet ainsi créé n'aura jamais de méthode. Cependant, si vous voulez cette fonctionnalité, vous devez transmettre cette information à une classe qui peut l'utiliser, par exemple.

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

Vous trouverez un exemple pratique de ceci ici .

Vous voudrez peut-être voir comment utiliser les interfaces TypeScript et JSON pour en apprendre un peu plus sur la façon dont cela fonctionne. 

14
Nypan

Je ne connais pas bien TypeScript, mais si je regarde le code JavaScript compilé, je remarque que tProduct n’est qu’un POJO, pas une instance de la classe Product (c.-à-d. tProduct instanceof Product === false). 

La raison pour laquelle Id ne commet pas d'erreur est que JSON.parse renvoie un objet avec une propriété Id.

Pour voir comment désérialiser vers un type TypeScript, vous pouvez vérifier la réponse suivante: Comment initialiser un objet TypeScript avec un objet JSON

1
Dustin Hodges