2016-08-18 3 views
1

Kann jemand bitte erklären, warum ich nicht intellisense in 'setItem' Funktion für 'diese' Variable. Mein Verständnis sollte auf '_storageAdapter'-Eigenschaft beschränkt werden?TypeScript - 'Dies' ist standardmäßig 'any'

class TestClass { 
private testOne =() => { 
} 

_storageAdapter: { 
    toType: (obj: any) => string, 
    getItem: (key: string) => void, 
    setItem: (key: string, value: string) => void, 
} 
= { 
    toType: (obj: any) => { 
     return "hello"; 
    }, 
    getItem: (key: string) => { 
     this.testOne() // this is class scoped; 
    }, 
    setItem: function (key: string, value: any) { 
     this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any' 
    } 
} 

}

Antwort

2

Regular js Funktionen speichern nicht den Umfang von this, zum Beispiel:

class A { 
    obj = { 
     withoutScope: function() { 
      console.log(this); 
     }, 

     withScope:() => { 
      console.log(this); 
     } 
    } 
} 

in Compiliert:

var A = (function() { 
    function A() { 
     var _this = this; 
     this.obj = { 
      withoutScope: function() { 
       console.log(this); 
      }, 
      withScope: function() { 
       console.log(_this); 
      } 
     }; 
    } 
    return A; 
}()); 

Beachten Sie den Unterschied zwischen den beiden console.log: Die withoutScope hat this whil e withScope hat _this (oben definiert als var _this = this).
Dies ist, wie der Typskript-Compiler die arrow function übersetzt, aber wenn Sie es kompilieren mit ES6 Ziel dann wird es als Pfeil-Funktion ohne die Verwendung des _this = this Trick, aber das Ergebnis wird das gleiche sein.

Wenn Sie diese Methoden aufrufen, erhalten Sie:

let a = new A(); 
a.obj.withoutScope(); // Object {} 
a.obj.withScope(); // A { obj: Object } 

(code in playground)

Das gleiche in Ihrem Beispiel der Fall ist, sind die ersten beiden Funktionen Pfeil Funktionen, die den richtigen Umfang von this halten, aber die das dritte nicht.
Sie können entweder einen Pfeil Funktion auch dort verwenden, oder Sie können die Function.prototype.bind Funktion:

setItem: function (key: string, value: any) { 
    this.toType(value); // this should be property scoped? but no intellisense? its just set to 'any' 
}.bind(this) 

Aber es wird wahrscheinlich nur zur Laufzeit helfen, wie ich bin nicht sicher, dass Ihr intellisense dass bekommen.

+0

Danke. Ich denke, mein Problem ist, dass es keine Möglichkeit gibt, die Build- oder Kompilierzeit zu überprüfen. Sie können this.ANYTHING in setItem eingeben und es bremst nur zur Laufzeit. Unabhängig davon, ob Sie einen Fettpfeil oder reguläre Funktionen verwenden, können Sie die interne Funktion innerhalb von _storageAdapter nicht außerhalb der _storageAdapter-Eigenschaft aufrufen. Bummeln – dotsa

+0

Sie können eine Pfeilfunktion wie mit den anderen zwei verwenden, aber warum haben Sie nicht nur diese Funktionen als Klassenmethoden und Sie halten sie in diesem Objekt? –

+0

Ja.Ich kann das zu einer Schnittstelle wahlweise und einer Klasse extrahieren. Ich habe nur versucht zu sehen, wie weit ich TS drücken kann, bevor es mir nicht stark typisierte Objekte und Intellisense geben wird. – dotsa

1

Vereinfachtes Beispiel:

class TestClass { 
    private testOne =() => { 
    } 

    _storageAdapter: { 
     getItem: (key: string) => void, 
     setItem: (key: string, value: string) => void, 
    } 
    = { 
     getItem: (key: string) => { 
      this.testOne() // this is class scoped; 
     }, 
     setItem: function (key: string, value: any) { 
      this.somethingThatDoesNotExist(); // this should be property scoped? but no intellisense? its just set to 'any' 
     } 
    } 
} 

Der Grund dafür ist, dass function nicht this nicht erfassen, und es wird wirklich auf den Benutzer der Funktion, wie sie es nennen.

Eine Pfeilfunktion erfasst this, also hat Typoskript stärkere Garantie.

Mehr

Einige Flaggen, die Sie verhindern überrumpelt zu werden: noImplicitAnyhttps://basarat.gitbooks.io/typescript/content/docs/options/noImplicitAny.html

Verwandte Themen