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

[TypeScript] ParseError when declaring class fields #137

Closed
idiotWu opened this issue Oct 10, 2021 · 7 comments
Closed

[TypeScript] ParseError when declaring class fields #137

idiotWu opened this issue Oct 10, 2021 · 7 comments

Comments

@idiotWu
Copy link

idiotWu commented Oct 10, 2021

The Problem

Declaring any class fields inside svelte components will cause a ParseError in eslint, for example:

App.svelte:

<script lang="ts">
  class Test {
    static value = 'test';
    this_breaks_too: number;
  }
</script>

eslint outputs:

.../App.svelte
  3:18  error  Unexpected token  ParseError

✖ 1 problem (1 error, 0 warnings)

Steps to Reproduce

  1. clone this repo: https://github.com/idiotWu/svelte-eslint-test
  2. run npm install
  3. run npm run lint
@Conduitry
Copy link
Member

This syntax is unsupported in ESLint itself in regular JS files - eslint/eslint#15016 - Once ESLint supports this and you've upgraded, this should work without any further changes on Svelte's side.

@idiotWu
Copy link
Author

idiotWu commented Oct 10, 2021

This syntax is unsupported in ESLint itself in regular JS files

But the above code was written in TypeScript, and the ParseError will disappear if you put the same code into a normal .ts file.

Update: this issue has nothing to do with the static field syntax, any class field declaration, for example value: number, will break eslint. @Conduitry

@idiotWu idiotWu changed the title [TypeScript] ParseError when using class syntax inside svelte components [TypeScript] ParseError when declaring class fields Oct 10, 2021
@idiotWu
Copy link
Author

idiotWu commented Oct 11, 2021

I think this problem is caused by the target: ts.ScriptTarget.ESNext option below:

compilerOptions: {
target: ts.ScriptTarget.ESNext,
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve,
sourceMap: true
},

TypeScript (4.4.3 in my environment) will preserve class field declarations when targeting ESNext, for example,

// source.ts
export class Test {
  static value = 'test';
  this_breaks_too: number;
}

yields

// source.js
export class Test {
    static value = 'test';
    this_breaks_too;
}

which breaks eslint. Is there any reason that this plugin uses the above compiler options instead of a user-defined tsconfig.json?

@iva2k
Copy link

iva2k commented Dec 3, 2022

@Conduitry: The issue you linked in eslint eslint/eslint#15016 which substantiated closing this one is completely unrelated, it talks only about static variables. It has been fixed in eslint but it has no bearing here - this issue remains broken.

This issue at hand seems to fail to parse into valid code, so it is not an eslint rule that fails, but it throws "error Unexpected token ParseError", which does not seem to be originating in eslint, but perhaps in svelte compiler after typescript transpiler. All samples below fail:

<script lang="ts">
  class Test1 {
    value = 'test';
    this_breaks_too: number;
  }
</script>
<script>
  class Test2 {
    value = 'test';
    this_breaks_too = 0;
  }
</script>

Per sveltejs/svelte#6900, setting lib: ["esnext"] in "tsconfig.json" makes svelte compiler produce invalid code. That is what this module does on L239:

compilerOptions: {
target: ts.ScriptTarget.ESNext,
importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Preserve,
sourceMap: true
},

Setting lib: ["es2020"] and "target": "es2020" fixes the problem in sveltejs/svelte#6900.

I also patched L239 and it fixed the problem (ParseError is gone and eslint gets to report its findings per the rules):

function compile_code(text, compiler, processor_options) {
	const ts = processor_options.typescript;
	if (!ts) {
		return compiler.compile(text, { generate: false, ...processor_options.compiler_options });
	} else {
		const ts_options = {
			reportDiagnostics: false,
			compilerOptions: {
-				target: ts.ScriptTarget.ESNext,
+				target: ts.ScriptTarget.ES2020,
  10:9  warning  'Test1' is defined but never used  @typescript-eslint/no-unused-vars
  14:9  warning  'Test2' is defined but never used  @typescript-eslint/no-unused-vars

@Conduitry: please reopen this issue. And as a fix allow compiler options from tsconfig.json to pass into typescript compiler, or at least allow compiler options in .eslintrc, so the lib, target and module can be set.

@jescalan
Copy link

jescalan commented Jan 6, 2023

Just want to note that this is still an issue for me - a basic class property annotation inside a script block with lang="ts" will still emit the following warning, though it will compile without issue as long as you add "target": "ES2021" to your typescript config.

Unexpected token
If you expect this syntax to work, here are some suggestions: 
If you use typescript with `svelte-preprocess`, did you add `lang="ts"` to your `script` tag? 
Did you setup a `svelte.config.js`? 
See https://github.com/sveltejs/language-tools/tree/master/docs#using-with-preprocessors for more info.svelte(parse-error)

@knd775
Copy link

knd775 commented Jan 6, 2023

Yep. It even happens in a fresh SvelteKit demo app.

pnpm create svelte@latest myapp # Select demo app + TS + ESLint
cd myapp
eslint .

results in:

~\myapp\src\routes\Counter.svelte
  10:19  error  Unexpected token  ParseError

~\myapp\src\routes\sverdle\+page.svelte
  4:14  error  Unexpected token  ParseError

✖ 2 problems (2 errors, 0 warnings)

@justingolden21
Copy link

Any progress on this? It triggers only in .svelte files and not .ts files, getting a ParseError on literally every single svelte file containing a single line of ts. happens in demo app as knd775 pointed out... Kinda wild that the demo app has this problem and there's no automated check before a deploy that running the basic scripts on the demo app actually succeeds... Separate issue though.

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

No branches or pull requests

6 participants