1

Unten ist eine sehr vereinfachte Version von Code, die ich an Google weitergeben Closure Compiler:Google Closure Compiler beschwerte sich über XMLHttpRequest.response Typ

"use strict"; 

var xhr = new XMLHttpRequest(); 

xhr.open("GET", "somefile", true); 
xhr.responseType = "arraybuffer"; 

xhr.addEventListener(
    'load', 
    function() {  
    var data = new Uint8Array(xhr.response); 
    /* ... do something ... */ 
    } 
); 

Dies ist im Grunde eine Ajax-Abfrage unformatierte binäre Daten abzurufen und es funktioniert wie erwartet.

jedoch gibt der Compiler die folgende Warnung:

WARNING - actual parameter 1 of Uint8Array does not match formal parameter 
found : * 
required: (Array<number>|ArrayBuffer|ArrayBufferView|null|number) 
     var data = new Uint8Array(xhr.response); 
           ^

ich einige Zeit damit verbracht habe versucht, es mit JSDoc Richtlinien zu beheben, um ausdrücklich die Art der ‚xhr.response‘ als ‚Arraybuffer zu definieren ".

Zum Beispiel:

/** @property {ArrayBuffer} response */ 
var xhr = new XMLHttpRequest(); 

aber nichts funktionierte.

Was schließlich Arbeit tat, war die Variablendeklaration von seiner Initialisierung zu trennen, ohne Zugabe von JSDoc Richtlinie:

var xhr; 
xhr = new XMLHttpRequest(); 

keine Warnung mehr.

Das Problem ist, dass ich es nicht verstehe. Warum behebt es das Problem? War es wirklich richtig?

Antwort

1

Warum behebt es das Problem?

Ich glaube, Sie haben einen Fehler im Closure-Compiler gefunden. Sie könnten report an issue darüber.

Die Aufteilung dieser Zeile in zwei Zeilen sollte nicht das ändern, was der Compiler tut. Der Übersichtlichkeit halber sehen Sie hier die Linie, die Sie teilen.

var xhr; 
xhr = new XMLHttpRequest(); 

I bestätigt den Bericht online closure compiler mit Optimierung auf Erweitert verwenden.

War es wirklich das Richtige zu tun?

Die Definition im html5.js extern ist

/** 
* @type {*} 
* @see http://dev.w3.org/2006/webapi/XMLHttpRequest-2/#the-responsetype-attribute 
*/ 
XMLHttpRequest.prototype.response; 

So ist der Fehler, den Sie vernünftig bekam war. Fix es mit einem Typ-Cast:

var r = /** @type {!ArrayBuffer}*/(xhr.response); 
var data = new Uint8Array(r); 

Versuchen Sie Folgendes in der online closure compiler mit Optimierung auf Erweitert.

"use strict"; 

var xhr = new XMLHttpRequest(); 

xhr.open("GET", "somefile", true); 
xhr.responseType = "arraybuffer"; 

xhr.addEventListener(
    'load', 
    function() { 
    var r = /** @type {!ArrayBuffer}*/(xhr.response); 
    var data = new Uint8Array(r); 
    /* ... do something ... */ 
    } 
); 

Es funktioniert für mich dort. Ich erhalte auch den Fehler, den Sie mit Ihrer ursprünglichen Version gemeldet haben. Beachten Sie jedoch, dass bei der Optimierung auf "Einfach" der Fehler nicht angezeigt wird.

+0

Vielen Dank für Ihre Analyse und die vorgeschlagene Lösung. Es ist mir irgendwie nicht gelungen, mit der korrekten Syntax '/ ** @type {! ArrayBuffer} */(xhr.response)' zu kommen. Ich denke, ich habe das ohne Klammern versucht. – Arnauld

+0

Eine Art Besetzung ist definitiv die richtige Lösung - es ist kein Fehler. –

+0

@Chad: Ja, die Besetzung ist die richtige Lösung. Aber die Tatsache, dass die Warnung verschwindet, wenn ich die Zeile _ohne_ eine Typaufteilung spalte, sieht sehr nach einem Compilerfehler aus. – Arnauld