visual studio - Typescript anpassad verktyg, transpiler, tillägg


Jag skulle vilja ändra/kontrollera .ts-filer innan tsc startar sin transpileringsprocess, liknande vad Roslyn erbjuder för C#.

Detta är användbart för statisk typkontroll. Till exempel kräver korrekt och kort Immutable Record-implementering kodändring/statisk kontroll vid kompileringstid, vilket kan göras med Flow:

@Record(Person)
interface IPerson {  
  givenName: string;
  familyName: string;
}

och sedan kunde en anpassad tsc-transpiler ändra koden till:

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 skulle vara trevligt att se anpassade kompilationsfel direkt som det görs nu med Visual Studio och Visual Studio Code, som kör special tsc watch, inte som en del av webpack-bundling eller anpassad gulp-uppgift. Det finns ett API för Typescript, men hur får man det att fungera smidigt med tsc i VS/VS Code/Atom?

Uppdatera med exempel

Målet är bara att skriva

@Record(Person)
interface IPerson {  
  givenName: string;
  familyName: string;
}
  1. Klassen Person kommer att auto-genereras baserat på gränssnittet IPerson som visas tidigare.

  2. Det kommer att vara möjligt att instansiera objektet:

    let instance = new Person({givenName: "Emma", familyName: "Watson"});

    Alla felaktiga egenskaper kommer att orsaka ett kompileringsfel:

    let instance = new Person({nonExistedProperty: "Emma"}); //error

    Fel: Egenskapen 'nonExistedProperty' finns inte i klassen Person-konstruktorn;
    Fel: Egenskapen 'givenName' är obligatorisk i klassen Person-konstruktorn;
    Fel: Egenskapen 'familyName' är obligatorisk i klassen Person-konstruktorn;

  3. Existerande objekt bör kunna uppdateras delvis

    let instance=new Person({givenName: "Emma", familyName: "Watson"}); instance.Update({givenName: "Luise"});

    instance.givenName === "Luise"; //SANT;
    instance.familyName === "Watson"; //SANT;

  4. Alla egenskaper är skrivskyddade

    let instance=new Person({givenName: "Emma", familyName: "Watson"}); instance.givenName="John"; //fel

    Fel: Egenskapen 'givenName' är skrivskyddad;

  5. Equals-metoden är autogenererad. Den kan baseras på hash eller något annat, men bör vara snabb och ge en djupgående kontroll.

    let instance1=new Person({givenName: "Emma", familyName: "Watson"});
    let instance2=new Person({givenName: "Emma", familyName: "Watson"});

    instance1.Equals(instance2); //TRUE

    Det kan också ha en plats för att kontrollera skapade instanser, och om en post med samma parametrar finns i den interna ordlistan så returnerar den bara referensen till detta objekt:

    let instance1=new Person({givenName: "Emma", familyName: "Watson"});
    let instance2=new Person({givenName: "Emma", familyName: "Watson"});

    instance1 == instance2; //SANT
    instance1 === instance2; //SANT

Svar #1

Kanske istället för att skriva din egen TypeScript (pre) processor, kan du uppnå dina mål genom att använda TypeScript-dekoratörer.

Detta exempel är från 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

Detta är vad jag har hittat hittills. Det finns inget enkelt sätt att göra det just nu (2017).

En lösning är att skapa ett anpassat plugin som kommer att använda Typescript API. Det kommer också att köra tjänsterna en andra gång i sin egen sandbox tillsammans med TS-tjänster i VS Code, Atom eller VS. Dessutom kräver varje IDE att sitt eget plugin skapas som ett omslag ovanpå ditt kärnplugin/tjänst.

På detta sätt har vissa människor redan gjort linters, till exempel vscode-ng-language-service och ng2linter.

Microsoft har #6508-biljetten för TypeScript-utbyggbarhet, vilket kommer att göra de begärda funktionerna möjliga och enkla att implementera.

För dem som programmerar i C# och F# kan det vara bättre att använda möjligheterna med Roslyn istället för att vänta på TypeScript-tillägg. Kod skriven i C# kan transpileras till TypeScript eller JavaScript. Det öppnar också breda möjligheter för alla typer av kontroller och anpassade modifieringar. Och naturligtvis ligger det närmare DRY-principen om samma logik finns i .NET och TypeScript/Javascript. Bridge.NET använder inte Roslyn, men har en bra implementation. Rosetta-projektet för .NET 4 och Roslyn verkar vara en bra början.

Relaterade artiklar