visual studio - Typescript tilpasset verktøy, transpiler, utvidelse
Jeg vil gjerne endre/sjekke .ts-filer før tsc starter sin transpileringsprosess, på en måte som ligner det Roslyn tilbyr for C#.
Dette er nyttig for statisk typekontroll. For eksempel krever korrekt og kort Immutable Record-implementering kodeendring/statisk sjekk under kompilering, slik det kan gjøres med Flow:
@Record(Person)
interface IPerson {
givenName: string;
familyName: string;
}
og deretter kunne en tilpasset tsc-transpiler endre koden til:
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
});
}
}
Det ville være fint å se egne kompilasjonsfeil umiddelbart slik det gjøres nå med Visual Studio og Visual Studio Code, som kjører spesial tsc watch, ikke som en del av webpack-bundling eller egendefinert gulp-oppgave. Det finnes et API for Typescript, men hvordan få det til å fungere sømløst med tsc i VS/VS Code/Atom?
Oppdatering med eksempler
Målet er bare å skrive
@Record(Person)
interface IPerson {
givenName: string;
familyName: string;
}
Klassen
Personvil bli auto-generert basert på grensesnittetIPersonsom vist tidligere.Det vil være mulig å instansiere objektet:
let instance = new Person({givenName: "Emma", familyName: "Watson"});Enhver feil eiendom vil føre til en kompileringsfeil:
let instance = new Person({nonExistedProperty: "Emma"}); //errorFeil: Egenskapen 'nonExistedProperty' eksisterer ikke i Person-konstruktøren;
Feil: Egenskapen 'givenName' er påkrevd i Person-konstruktøren;
Feil: Egenskapen 'familyName' er påkrevd i Person-konstruktøren;Eksisterende objekt bør kunne oppdateres delvis
let instance=new Person({givenName: "Emma", familyName: "Watson"});instance.Update({givenName: "Luise"});instance.givenName === "Luise"; //SANT;
instance.familyName === "Watson"; //SANT;Alle egenskaper er skrivebeskyttet
let instance=new Person({givenName: "Emma", familyName: "Watson"});instance.givenName="John"; //feilFeil: Egenskapen 'givenName' er skrivebeskyttet;
Equals-metoden er autogenerert. Den kan baseres på hash eller noe annet, men bør fungere raskt og gi en grundig sjekk.let instance1=new Person({givenName: "Emma", familyName: "Watson"});
let instance2=new Person({givenName: "Emma", familyName: "Watson"});instance1.Equals(instance2); //TRUEDet kan også ha en plass for å kontrollere opprettede instanser, og hvis en post med de samme parameterne finnes i intern ordbok, returnerer den bare referansen til dette objektet:
let instance1=new Person({givenName: "Emma", familyName: "Watson"});
let instance2=new Person({givenName: "Emma", familyName: "Watson"});instance1 == instance2; //SANN
instance1 === instance2; //SANN
Svar #1
Kanskje i stedet for å skrive din egen TypeScript (pre) prosessor, kunne du oppnå målene dine ved å bruke TypeScript-dekoratører.
Dette eksemplet er fra https://www.typescriptlang.org/docs/handbook/decorators.html:
@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
Svar #2
Dette er hva jeg har funnet så langt. Det finnes ingen enkel måte å gjøre det på for øyeblikket (2017).
En løsning er å lage en tilpasset plugin som vil bruke Typescript API. Den vil også kjøre tjenestene en gang til i sitt eget sandkassemiljø sammen med TS-tjenestene i VS Code, Atom eller VS. I tillegg vil hver IDE kreve at sin egen plugin blir laget som en wrapper på toppen av din kjerneplugin/tjeneste.
På denne måten har noen allerede laget linters, for eksempel vscode-ng-language-service og ng2linter.
Microsoft har #6508-billett for TypeScript-utvidbarhet, som vil gjøre de forespurte funksjonene mulige og enkle å implementere.
For de som programmerer i C# og F# kan det være bedre å bruke mulighetene i Roslyn i stedet for å vente på TypeScript-utvidelser. En kode skrevet i C# kan transpileres til TypeScript eller JavaScript. Det åpner også for mange muligheter for all slags kontroll og tilpasninger. Og selvfølgelig er det nærmere prinsippet om DRY hvis den samme logikken finnes i .NET og TypeScript/JavaScript. Bridge.NET bruker ikke Roslyn, men har en god implementering. Rosetta-prosjektet for .NET 4 og Roslyn ser ut til å være et godt utgangspunkt.
