Chciałbym zmienić/sprawdzić pliki .ts
, zanim tsc
rozpocznie proces transpozycji, podobny do tego, co Roslyn zapewnia C#.Niestandardowe narzędzie maszynowe, transpilator, rozszerzenie
Jest to przydatne do sprawdzania typu statycznego. Na przykład, odpowiednie i krótkie Immutable Record
realizacja wymaga Kod zmieniania/statyczne sprawdzanie w czasie kompilacji, jak można to zrobić z Flow:
@Record(Person)
interface IPerson {
givenName: string;
familyName: string;
}
a następnie zwyczaj TSC transpiler mógłby zmodyfikować kod do:
interface IPersonParams {
givenName?: string;
familyName?: string;
}
@Record()
class Person {
private readonly __givenName;
private readonly __familyName;
constructor(init) {
this.__givenName = init.givenName;
this.__familyName = init.familyName;
}
get givenName() {
return this.__givenName;
}
get familyName() {
return this.__familyName;
}
update(update: IPersonParams) {
// ignore the bug when undefined param is passed
return new Person({
givenName: update.givenName || this.__givenName,
familyName: update.familyName || this.__familyName
});
}
}
Byłoby miło zobaczyć natychmiastowe błędy kompilacji niestandardowej, ponieważ teraz jest to robione przy użyciu Visual Studio i Visual Studio Code, które uruchamiają specjalne tsc watch
, a nie jako część pakowania pakietów internetowych lub niestandardowych zadań gulp. Jest API dla Typescript, ale jak sprawić, by działał bezproblemowo z tsc
w VS/VS Code/Atom
?
Aktualizacja z przykładów
Celem jest po prostu napisać
@Record(Person)
interface IPerson {
givenName: string;
familyName: string;
}
Klasa
Person
będą automatycznie generowane na podstawie interfejsuIPerson
jak pokazano wcześniej.Będzie to możliwe do wystąpienia obiektu:
let instance = new Person({givenName: "Emma", familyName: "Watson"});
Wszelkie nieprawidłowe nieruchomość podniesie błąd kompilacji:
let instance = new Person({nonExistedProperty: "Emma"}); //error
Błąd: własność 'nonExistedProperty' nie istnieje w klasie Osoba konstruktor;
Błąd: Właściwość 'givenName' jest wymagana w klasie Osoba konstruktor;
Błąd: Właściwość "familyName" jest wymagana w klasie Osoba konstruktor;Istniejący obiekt powinien móc być częściowo aktualizowana
let instance = new Person({givenName: "Emma", familyName: "Watson"});
instance.Update({givenName: "Luise"});
instance.givenName === "Luise"; //TRUE;
instance.familyName === "Watson"; //TRUE;
Wszystkie właściwości są tylko do odczytu
let instance = new Person({givenName: "Emma", familyName: "Watson"});
instance.givenName = "John"; //error
Błąd: właściwość "givenName" jest tylko do odczytu;
Equals
metoda jest autogenerowana.Może być oparty na haszyszu lub cokolwiek innego, ale powinien działać szybko i zapewniać dokładną kontrolę.let instance1 = new Person({givenName: "Emma", familyName: "Watson"});
let instance2 = new Person({givenName: "Emma", familyName: "Watson"});
instance1.Equals(instance2); //TRUE
Może także mieć miejsce do sterowania utworzonych kopii i jeśli rekord z tymi samymi parametrami istnieje w wewnętrznym słowniku to właśnie zwraca referencję do tego obiektu:
let instance1 = new Person({givenName: "Emma", familyName: "Watson"});
let instance2 = new Person({givenName: "Emma", familyName: "Watson"});
instance1 == instance2; //TRUE
instance1 === instance2; //TRUE
mógłbyś podać jedną lub więcej przykłady użycia? Jak wyglądałby kod użytkownika, gdy dekorator zostanie zinterpretowany tak, jak sobie wyobrażasz? Co byłoby możliwe, co byłoby ograniczone? – Benjamin
Właśnie przypomniałem sobie, że nie można opisywać interfejsów w TypeScripcie. Obejściem tutaj jest użycie klas zamiast interfejsów: 'interface A {} ... class B implementuje A {}' – Benjamin
@Benjamin problem jest głębszy niż adnotacje interfejsu. Kompilator nie może w pełni sprawdzić dynamicznie tworzonych obiektów. Adnotacje maszynopisu dopuszczają tylko obiekty tworzone dynamicznie, ale nie statyczne. Dlatego potrzebne jest niestandardowe narzędzie kompilacji pośredniej, które może tworzyć klasy (statyczne), które będą dodatkowo sprawdzane przez kompilator. – Artru