typescript - Kan en egenskaps-dekoratör definiera typen på dekoratörens egenskap?


Jag har en egenskapsdekorator som returnerar en egenskapsbeskrivare. Finns det ett sätt att tala om för kompilatorn vilken typ den dekorerade egenskapen x har via dekoratorn?

t.ex.

// returns a readonly string property descriptor
function d(target, key) {
    return {
        get: function() : string {return 'hello'}
    }
}

// would like type of property x to be `string` either inferred
// or taken from decorator getter signature
class A {
    @d()
    x 
}

Problemet jag försöker lösa är att eliminera extra arbete för användaren av dekoratorn - mina dekoratorer definierar egenskapen (inklusive typ) så att upprepa typen ( x: string i detta fall) är överflödigt. Det verkliga exemplet är databasobjekt där alla egenskaper (hundratals) är dekorerade. För närvarande har varje egenskap både dekoratorn OCH en specifik typannotering. Smärtpunkt uppstod när jag aktiverade --strictNullChecks, vilket innebär att hundratals egenskaper skulle behöva | null lagts till typen (eftersom databasen tillåter att null sätts som värde). Eftersom dekoratorn dikterar egenskapstypen hoppas jag kunna slopa typdeklarationen.

Jag ser att TS inkluderar en generell TypedPropertyDescriptor-deklaration men egenskapsdekorationer måste returnera void eller any annars ger kompilatorn fel.

Svar #1

Tyvärr tror jag inte att det du försöker göra för närvarande är möjligt i den nuvarande versionen av Typescript. Du försöker ändra signaturen för klassen A genom att implicit sätta typen för egenskapen x via dekoratorn, men det finns inget sätt för kompilatorn att veta vilken typ x ska ha och inget sätt för kompilatorn att veta att x ska ha get-metoden.

Det finns en stor tråd på GitHub om ett mycket liknande problem med klassdekorerare. https://github.com/Microsoft/TypeScript/issues/4881 Följ kanske den tråden om du är intresserad!

Du skulle kunna närma dig detta på ett annat sätt och tillhandahålla en generisk med begränsningar till A-klassen; dock är jag inte säker på vilket problem du försöker lösa, så det kanske inte är ett alternativ.