microsoft / microsoft/TypeScript

Improve type errors when applying a decorator to a member it does not support

Offen
#54,963 0 Kommentare 6 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Experience Enhancement Help Wanted Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

Suggestion

🔍 Search Terms

standard decorators auto accessor member class error message

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

The typings for standard decorators allow them to indicate through their types what they may and may not be applied to. Currently TypeScript correctly errors in these cases, but the error messages are fairly abstract. This is likely to hit people migrating from the experimental decorators particularly hard, as many property decorators will become accessor decorators, requiring decorated properties to add the auto accessor annotation.

On the Lit team we've been seeing this issue as we prepare to vend standard versions of our decorators, see related PRs https://github.com/lit/lit/pull/3982, https://github.com/lit/lit/pull/4009

📃 Motivating Example

Consider code like:

declare function decorate1(target: unknown, context: ClassAccessorDecoratorContext): void;
declare function decorate2(target: ClassAccessorDecoratorTarget<unknown, unknown>, context: ClassAccessorDecoratorContext): void;

class Foo {
  @decorate1 prop1 = '';

  @decorate2 prop2 = '';
}

playground link

The mistake made with this code is that prop1 and prop2 are properties, but they need to be accessors, so the fix is to change Foo to read:

class Foo {
  @decorate1 accessor prop1 = '';

  @decorate2 accessor prop2 = '';
}

However the type errors are not particularly helpful in indicating this! decorate1 is squiggled with:

Unable to resolve signature of property decorator when called as an expression.
  Argument of type 'ClassFieldDecoratorContext<Foo, string> & { name: "prop1"; private: false; static: false; }' is not assignable to parameter of type 'ClassAccessorDecoratorContext<unknown, unknown>'.
    Types of property 'kind' are incompatible.
      Type '"field"' is not assignable to type '"accessor"'.

and decorate2 is squiggled with:

Unable to resolve signature of property decorator when called as an expression.
  Argument of type 'undefined' is not assignable to parameter of type 'ClassAccessorDecoratorTarget<unknown, unknown>'.

It would likely require some special casing, but when there is a type error when applying a decorator, I think it would be better to give an error closer to:

decorator1 prop1 = ''
~~~~~~~~~~

'accessor' decorator is not applicable to a 'field'.

In IDEs, for the specific case of applying an accessor decorator to a field, this is an opportunity to provide the fix of adding the accessor modifier to the declaration, or remove it when applying a field decorator to an accessor.

💻 Use Cases

The experimental decorators were frequently applied to fields to run logic when a field was set (e.g. change detection, reactive rendering, etc). With standard decorators, that use case can't be met by a field decorator, an accessor decorator must be used. Auto accessors are provided to make this easy and give a good developer experience, but they're likely to only be used for decorators, and developers will not be accustomed to using them.

When a developer is updating a code base to use standard decorators, or contributing to one that's already using them, they're likely to run into this issue and be quite confused until they can find a Q&A answer about this error message somewhere.

In the meantime, we'll be documenting this issue everywhere we talk about using standard decorators with Lit.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Verwende das motivierende Beispiel und seinen TypeScript Playground-Link als Ausgangspunkt für die Reproduktion. Vergleiche die aktuellen Diagnosen für decorate1 und decorate2 bei Feldern mit der vorgeschlagenen Formulierung für Accessor/Feld; abgeschlossen ist die Aufgabe, wenn die Diagnosen die nicht unterstützte Member-Art identifizieren und gegebenenfalls auf das Hinzufügen oder Entfernen des Accessor-Modifizierers hinweisen.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.