Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decorators don't work in TypeScript after following Developer Preview guide #5087

Open
jparta opened this issue Jan 2, 2025 · 9 comments
Open
Labels
bug typescript Typescript related bugs

Comments

@jparta
Copy link

jparta commented Jan 2, 2025

Description

Steps to Reproduce

I followed this guide: https://developer.salesforce.com/docs/platform/lwc/guide/ts.html

import { LightningElement, api } from 'lwc';

export default class Test extends LightningElement {
  @api testTesting;
}

Expected Results

Typescript accepts the decorator @api

Actual Results

In VS Code, I get the following TypeScript error:

Unable to resolve signature of property decorator when called as an expression.
  Argument of type 'ClassFieldDecoratorContext<Enhancer, any> & { name: "testTesting"; private: false; static: false; }' is not assignable to parameter of type 'string | symbol'.ts(1240)

(alias) const api: PropertyDecorator
import api

Decorator to mark public reactive properties

This prevents deploying to org.

Version

{
  "name": "salesforce-app",
  "private": true,
  "version": "1.0.0",
  "description": "Salesforce App",
  "scripts": {
    "lint": "eslint **/{aura,lwc}/**/*.js",
    "test": "npm run test:unit",
    "test:unit": "sfdx-lwc-jest",
    "test:unit:watch": "sfdx-lwc-jest --watch",
    "test:unit:debug": "sfdx-lwc-jest --debug",
    "test:unit:coverage": "sfdx-lwc-jest --coverage",
    "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
    "prettier:verify": "prettier --check \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
    "postinstall": "husky install",
    "precommit": "lint-staged",
    "ts-build": "tsc --project force-app/main/default/lwc",
    "build-and-deploy": "npm run ts-build && sfdx project deploy start"
  },
  "devDependencies": {
    "@lwc/eslint-plugin-lwc": "^1.8.2",
    "@prettier/plugin-xml": "^3.2.2",
    "@salesforce/eslint-config-lwc": "^3.2.3",
    "@salesforce/eslint-plugin-aura": "^2.0.0",
    "@salesforce/eslint-plugin-lightning": "^1.0.0",
    "@salesforce/lightning-types": "^0.2.1",
    "@salesforce/sfdx-lwc-jest": "^3.1.0",
    "eslint": "^8.11.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-jest": "^27.6.0",
    "husky": "^8.0.3",
    "lint-staged": "^15.1.0",
    "lwc": "^8.8.0",
    "prettier": "^3.1.0",
    "prettier-plugin-apex": "^2.0.1",
    "typescript": "^5.6.3"
  },
  "lint-staged": {
    "**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [
      "prettier --write"
    ],
    "**/{aura,lwc}/**/*.js": [
      "eslint"
    ]
  }
}
  • LWC: 8.12.2
@nolanlawson nolanlawson added bug typescript Typescript related bugs labels Jan 2, 2025
@nolanlawson
Copy link
Collaborator

Thanks for opening the issue! By any chance could you share a Git repo / Gist / TypeScript playground / etc to help repro?

@jparta
Copy link
Author

jparta commented Jan 2, 2025

@nolanlawson

I used the code snippet I wrote above and the TS guide to create this repro: https://github.com/jparta/LWC_decorator_repro

You'll still have to follow the TS guide to get your environment to the state that I have it in.

TS guide again: https://developer.salesforce.com/docs/platform/lwc/guide/ts.html

@jparta
Copy link
Author

jparta commented Jan 7, 2025

@nolanlawson
Any updates?

@wjhsf
Copy link
Contributor

wjhsf commented Jan 7, 2025

Argument of type 'ClassFieldDecoratorContext<Enhancer, any> & { name: "testTesting"; private: false; static: false; }' is not assignable to parameter of type 'string | symbol'.ts(1240)

This looks like you may have experimentalDecorators: true in your tsconfig.json, but it should be set to false.

@jparta
Copy link
Author

jparta commented Jan 8, 2025

@wjhsf

Did you check the repro I linked to?

The guide states

Open tsconfig.json and make sure the experimentalDecorators flag is unset or set to false.

From repro:
https://github.com/jparta/LWC_decorator_repro/blob/main/force-app/main/default/lwc/tsconfig.json

{
    "extends": "../../../../.sfdx/tsconfig.sfdx.json",
    "include": [
        "**/*.ts",
        "../../../../.sfdx/typings/lwc/**/*.d.ts"
    ],
    "exclude": [
        "**/__tests__/**"
    ]
}

Extended tsconfig.sfdx.json, which is unmodified after being created by VS Code command SFDX: Create Project:

{
    "compilerOptions": {
        "skipLibCheck": true,
        "target": "ESNext",
        "module": "NodeNext",
        "paths": {
            "c/decoratorRepro": [
                "<path to repro>"
            ]
        }
    }
}

@wjhsf
Copy link
Contributor

wjhsf commented Jan 9, 2025

Looks like you're using the VS Code extension, which is known to be outdated, so you must use experimentalDecorators: true, rather than false. See #2078 (comment) for details.

@wjhsf wjhsf closed this as completed Jan 9, 2025
@jparta
Copy link
Author

jparta commented Jan 10, 2025

@wjhsf
This issue is not solved.

The TS guide says

Open tsconfig.json and make sure the experimentalDecorators flag is unset or set to false.

If I use this compilerOptions, there are no TS errors and deployment works

  "compilerOptions": {
    "experimentalDecorators": true,
  }

But upon opening the page which includes the component, I get this error, with no errors in the console:

Looks like there's a problem.

Unfortunately, there was a problem. Please try again. If the problem continues, get in touch with your administrator with the error ID shown here and any other related details.

I've updated the repro to include exposing the component, a text for when it succesfully loads, and setting experimentalDecorators: true.

I remember that I tried setting experimentalDecorators: true earlier as well, and got false hope that this would solve the issue, until reloading the app page and seeing the Looks like there's a problem. error.

My previous config (built according to a previuous version of the TS guide) had
  "compilerOptions": {
    "experimentalDecorators": false,
    "target": "ESNext",
    "module": "Preserve"
  }

Which resulted in the error

│ LightningComponentBundle │ multiUseButton │ [Line: 34, Col: 0] LWC1535: Unexpected plugin compilation error: Plugin - lwc, Hook - transform, Cause - SyntaxError:                                                               │             │
│                          │                │ /home/sfdc/tools/sfdc-lwc-compiler/11.32768.0/multiUseButton.js: LWC1104: "api" can only be used as a class decorator                                                               │             │
│                          │                │ 32 |   }                                                                                                                                                                            │             │
│                          │                │ 33 | }                                                                                                                                                                              │             │
│                          │                │ > 34 | __decorate([api], MultiUseButton.prototype, "state", void 0);                                                                                                                │             │
│                          │                │ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  

@wjhsf
Copy link
Contributor

wjhsf commented Jan 10, 2025

I originally closed this issue because it was already reported in #2078, but after reading through that issue again, I think it's become a bit cluttered. I'll leave this one open as it's more narrowly scoped to just the incompatibility with the VS Code extension.

Sorry for the misdirection, there's more going on here than I remembered!


To summarize the findings in the other issue, the LWC compiler requires that decorator syntax (@api) be preserved. The required compiler options to have TypeScript preserve decorators are "experimentalDecorators": false and "target": "ESNext". If you use "experimentalDecorators": true or any different target, then the decorators get transformed (into __decorate or __esDecorate` function calls), and the LWC can't handle that.

LWC only began supporting "experimentalDecorators": false in v7. Older versions require the option to be set to true. And the VS Code extension currently injects types from an older version of LWC. As a consequence, if you are using the VS Code extension, you must prefix all of your decorator usage with // @ts-expect-error or // @ts-ignore. For example:

export default class extends LightningElement {
  // @ts-expect-error The Salesforce VS Code extension doesn't like modern decorators
  @api someProp?: string;
}

This issue will be resolved when the VS Code extension can be updated to use the latest version of LWC, tracked at forcedotcom/lightning-language-server#602. It also may be resolved if we can restore support for experimental decorators (#5084 (comment)), but that might not be possible.

@wjhsf wjhsf reopened this Jan 10, 2025
@wjhsf
Copy link
Contributor

wjhsf commented Jan 10, 2025

I've submitted changes to document this issue in the TypeScript Dev Preview guide. The changes should be live next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug typescript Typescript related bugs
Projects
None yet
Development

No branches or pull requests

3 participants