Repository: TypeScript
Issue: Improve type errors when applying a decorator to a member it does not support
Labels: Suggestion,Help Wanted,Experience Enhancement

# Suggestion

## 🔍 Search Terms

standard decorators auto accessor member class error message

## ✅ Viability Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-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:

```typescript
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](https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtX1DBxigxAEYAKDWAcxAwC540BrVHAd1QBp4jUZAB5N4AYWgBnSQEEwYENOIARcMVLExeYRgCUzAG44swANwAoQtDhI0mXPkLqyAJmp0GzCVGlyFSmFUiEgxiABUPDAAeNg5uPliuVAA+PgEdLylZeUVJFTUQzW0QEX14IxMLc0gfSXgAMRwceABvc3h4AAEnEIp4AAcYHH7yeABeeABySaqO7oLSEBcBof7liemLAF9zIA)

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:

```typescript
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.