Skip to content

Commit 8fc99ee

Browse files
Copilotadamziel
andauthored
[meta] Add ESLint rule for Node.js type stripping compatibility (#2951)
## Motivation for the change, related issues Node.js type stripping (`--experimental-strip-types`) fails on TypeScript syntax with runtime semantics. This caused runtime errors like: ``` SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript parameter property is not supported ``` ## Implementation details Added the existing `@typescript-eslint/parameter-properties` ESLint rule to prevent TypeScript parameter properties that are unsupported by Node.js type stripping. - **Parameter properties** — `constructor(private foo: string)` → explicit property + assignment Fixed existing violations: - `blueprints-v1-handler.ts`, `blueprints-v2-handler.ts`, `website-page.ts`, `code-editor.tsx` — converted parameter properties to explicit declarations ## Testing Instructions (or ideally a Blueprint) ```bash npm run lint ``` Verify the rule catches new violations: ```typescript // Should error class Foo { constructor(private bar: string) {} } ``` <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > Start a new PR to add an eslint rule – only allow TypeScript syntax that's supported by Node.js type stripping (to prevent future errors such as this): > > Version number df6471b7770cee7792040577 copied to clipboard > Use Ctrl+C to stop the server > node:internal/modules/run_main:123 > triggerUncaughtException( > ^ > > file:///Users/mho/Work/projects/xdebug/wordpress-playground/packages/playground/blueprints/src/lib/v1/compile.ts:47 > export class InvalidBlueprintError extends Error { > constructor(message: string, public readonly validationErrors?: unknown) { > ^^^^^^^^^^^^^^^^^^^^^^^^^^ > super(message); > > SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript parameter property is n > 40 references > Copilot said: Let me search for more specific ESLint > Let me search for more specific ESLint configuration files in the repository:Based on my research into the WordPress Playground repository, I can see that: > > The repo already has a custom ESLint plugin at packages/meta/src/eslint-plugin-playground-dev/ with one existing rule (avoid-wordpress-builds-dependency) > The root .eslintrc.json already has some Node.js type stripping support with @typescript-eslint/consistent-type-imports rule enabled > The error you referenced is about TypeScript parameter properties (like public readonly validationErrors), which are not supported by Node.js type stripping. A new ESLint rule should be added to prevent this syntax. > > I'll create a PR that adds an ESLint rule to disallow TypeScript syntax that's unsupported by Node.js type stripping, specifically: > > Parameter properties (constructor(public foo: string)) > Enums (which also aren't supported by type stripping) > Namespaces </details> <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: adamziel <205419+adamziel@users.noreply.github.com>
1 parent 54138fb commit 8fc99ee

File tree

5 files changed

+22
-5
lines changed

5 files changed

+22
-5
lines changed

.eslintrc.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@
7878
"no-constant-condition": 0,
7979
"playground-dev/avoid-wordpress-builds-dependency": "error",
8080
// Node.js type stripping requires explicit type imports.
81-
"@typescript-eslint/consistent-type-imports": "error"
81+
"@typescript-eslint/consistent-type-imports": "error",
82+
// Disallow TypeScript parameter properties unsupported by Node.js type stripping.
83+
"@typescript-eslint/parameter-properties": "error"
8284
}
8385
},
8486
{

packages/playground/client/src/blueprints-v1-handler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import { collectPhpLogs, logger } from '@php-wasm/logger';
1111
import { consumeAPI } from '@php-wasm/universal';
1212

1313
export class BlueprintsV1Handler {
14-
constructor(private readonly options: StartPlaygroundOptions) {}
14+
private readonly options: StartPlaygroundOptions;
15+
16+
constructor(options: StartPlaygroundOptions) {
17+
this.options = options;
18+
}
1519

1620
async bootPlayground(
1721
iframe: HTMLIFrameElement,

packages/playground/client/src/blueprints-v2-handler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { collectPhpLogs, logger } from '@php-wasm/logger';
44
import { consumeAPI } from '@php-wasm/universal';
55

66
export class BlueprintsV2Handler {
7-
constructor(private readonly options: StartPlaygroundOptions) {}
7+
private readonly options: StartPlaygroundOptions;
8+
9+
constructor(options: StartPlaygroundOptions) {
10+
this.options = options;
11+
}
812

913
async bootPlayground(
1014
iframe: HTMLIFrameElement,

packages/playground/website/playwright/website-page.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import type { Page } from '@playwright/test';
22
import { expect } from '@playwright/test';
33

44
export class WebsitePage {
5-
constructor(public readonly page: Page) {}
5+
public readonly page: Page;
6+
7+
constructor(page: Page) {
8+
this.page = page;
9+
}
610

711
// Wait for WordPress to load
812
async waitForNestedIframes(page = this.page) {

packages/playground/website/src/components/site-manager/site-file-browser/code-editor.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ const loadLanguageExtension = async (
124124

125125
// Plugin to handle clicks below the content and move cursor to end of document
126126
class ClickBelowContentHandler implements PluginValue {
127-
constructor(private view: EditorViewType) {
127+
private view: EditorViewType;
128+
129+
constructor(view: EditorViewType) {
130+
this.view = view;
128131
this.handleClick = this.handleClick.bind(this);
129132
this.view.dom.addEventListener('mousedown', this.handleClick);
130133
}

0 commit comments

Comments
 (0)