From 592351e0245684c01d719d3259cdfcfd6a6d52a9 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Wed, 21 Oct 2026 22:04:34 +0800 Subject: [PATCH 1/5] fix: update --tsgo-experimental-api for typescript 7.1 --- .changeset/ripe-sloths-take.md | 5 + packages/language-server/package.json | 2 +- .../features/DiagnosticsProvider.ts | 144 ++++-- .../src/plugins/typescript-go/types.ts | 7 +- packages/language-server/src/svelte-check.ts | 13 +- .../features/diagnostics/index.test.ts | 17 +- .../expected_tsgo.json | 2 +- .../bind-this/expected_tsgo_svelte_4.json | 98 ++++ ...tedv2.json => expected_tsgo_svelte_5.json} | 16 +- .../svelte-element/expected_tsgo.json | 24 + packages/svelte-check/package.json | 2 +- packages/svelte-check/src/index.ts | 14 +- packages/svelte-check/src/tsgo.ts | 16 +- packages/svelte-check/test-sanity.js | 6 +- pnpm-lock.yaml | 426 ++++++++++++++++-- 15 files changed, 688 insertions(+), 104 deletions(-) create mode 100644 .changeset/ripe-sloths-take.md create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_4.json rename packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/{expectedv2.json => expected_tsgo_svelte_5.json} (71%) create mode 100644 packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected_tsgo.json diff --git a/.changeset/ripe-sloths-take.md b/.changeset/ripe-sloths-take.md new file mode 100644 index 000000000..2ce8df4bd --- /dev/null +++ b/.changeset/ripe-sloths-take.md @@ -0,0 +1,5 @@ +--- +'svelte-check': patch +--- + +fix: update --tsgo-experimental-api for typescript 7.1 diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 3c9ebd9e9..4922dea4f 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -44,7 +44,7 @@ "@types/mocha": "^10.0.10", "@types/node": "^18.0.0", "@types/sinon": "^7.5.2", - "@typescript/native-preview": "~7.0.0-dev.20260703.1", + "@typescript/native": "npm:typescript@7.1.0-beta", "cross-env": "^7.0.2", "mocha": "^11.7.6", "sinon": "^11.0.0", diff --git a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts index 272d9c871..5f7a2ce54 100644 --- a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts +++ b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts @@ -1,4 +1,3 @@ -import type { FileSystem } from '@typescript/native-preview/unstable/fs' with { 'resolution-mode': 'import' }; import fs from 'node:fs'; import { dirname } from 'node:path'; import path from 'path'; @@ -49,7 +48,7 @@ import { } from '../../typescript/features/utils'; import { isAttributeName, isEventHandler } from '../../typescript/svelte-ast-utils'; import { hasNonZeroRange, isSvelteFilePath, mapSeverity } from '../../typescript/utils'; -import { tsApiSync, tsAst } from '../types'; +import { tsApiSync, tsAst, tsFs } from '../types'; import { gatherIdentifiers, getStartOfNode, @@ -63,9 +62,18 @@ const D_SVELTE_TS_EXTENSION = '.d.svelte.ts'; const D_SVELTE_TS_LENGTH = D_SVELTE_TS_EXTENSION.length; const SVELTE_DTS_EXTENSION = '.svelte.d.ts'; +export interface TSModules { + apiModule: typeof tsApiSync; + astModule: typeof tsAst; + fsModule: typeof tsFs; + tsVersion: string; +} + export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { private readonly api: tsApiSync.API; private readonly tsApiModule: typeof tsApiSync; + + private readonly tsFsModule: typeof tsFs; private readonly files: FileMap = new FileMap(); private readonly virtualFiles: FileMap = new FileMap(); private readonly tsAstModule: typeof tsAst; @@ -78,8 +86,10 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { */ private projectConfig: ts.ParsedCommandLine; private pendingConfigLoading: Promise | undefined; + private readonly useStableApi: boolean; private createDocument: (filePath: string, content: string) => Document; + private snapshot: tsApiSync.Snapshot | undefined; private pendingChanges = { created: new Set(), @@ -88,14 +98,14 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { }; constructor( - apiModule: typeof tsApiSync, - tsAstModule: typeof tsAst, + modules: TSModules, tsconfigPath: string, ambientTypesSource: string, createDocument: (filePath: string, content: string) => Document ) { - this.tsApiModule = apiModule; - this.tsAstModule = tsAstModule; + this.tsApiModule = modules.apiModule; + this.tsAstModule = modules.astModule; + this.tsFsModule = modules.fsModule; this.tsconfigPath = tsconfigPath; this.virtualTsconfigPath = path.join( path.dirname(tsconfigPath), @@ -112,7 +122,9 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { emitJsDoc: true }; - this.api = new apiModule.API({ + const [major, minor] = (modules.tsVersion || '7.0').split('.').map(Number); + this.useStableApi = major > 7 || (major === 7 && minor >= 1); + this.api = new this.tsApiModule.API({ fs: this.createFsProxy() }); this.projectConfig = this.parseConfig(); @@ -155,12 +167,22 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { return [parserErrorDiag]; } - const virtualPath = toVirtualPath(tsDoc); + const path = toVirtualPath(tsDoc); const diagnostics: tsApiSync.Diagnostic[] = []; const program = project.program; - diagnostics.push(...(program.getSyntacticDiagnostics(virtualPath) || [])); - diagnostics.push(...(program.getSuggestionDiagnostics(virtualPath) || [])); - diagnostics.push(...(program.getSemanticDiagnostics(virtualPath) || [])); + if (this.useStableApi) { + this.api + .batch( + program.getSyntacticDiagnostics.gen(path), + program.getSuggestionDiagnostics.gen(path), + program.getSemanticDiagnostics.gen(path) + ) + .forEach((diag) => diagnostics.push(...diag)); + } else { + diagnostics.push(...(program.getSyntacticDiagnostics(path) || [])); + diagnostics.push(...(program.getSuggestionDiagnostics(path) || [])); + diagnostics.push(...(program.getSemanticDiagnostics(path) || [])); + } return mapAndFilterDiagnostics( this.tsAstModule, @@ -177,17 +199,50 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { await this.pendingConfigLoading; this.pendingConfigLoading = undefined; } - const snapshot = this.api.updateSnapshot({ - openProject: this.virtualTsconfigPath, - fileChanges: { - created: Array.from(this.pendingChanges.created), - changed: Array.from(this.pendingChanges.changed), - deleted: Array.from(this.pendingChanges.deleted) + + const changes = { + created: Array.from(this.pendingChanges.created), + changed: Array.from(this.pendingChanges.changed), + deleted: Array.from(this.pendingChanges.deleted) + }; + + let snapshot: tsApiSync.Snapshot; + if (this.useStableApi) { + if (!this.snapshot) { + this.snapshot = this.api.createSnapshot({ + openProjects: [this.virtualTsconfigPath], + fileNotifications: changes + }); + } else if ( + changes.created.length !== 0 || + changes.changed.length !== 0 || + changes.deleted.length !== 0 + ) { + this.snapshot = this.snapshot.update({ + fileNotifications: changes + }); } - }); + snapshot = this.snapshot; + } else { + // @ts-expect-error typescript < 7.1 + snapshot = this.api.updateSnapshot({ + openProject: this.virtualTsconfigPath, + fileChanges: { + created: Array.from(this.pendingChanges.created), + changed: Array.from(this.pendingChanges.changed), + deleted: Array.from(this.pendingChanges.deleted) + } + }); + } + this.pendingChanges.created.clear(); this.pendingChanges.changed.clear(); this.pendingChanges.deleted.clear(); + if (this.useStableApi) { + const project = snapshot.getConfiguredProject(this.virtualTsconfigPath); + return project; + } + // @ts-expect-error typescript < 7.1 const project = snapshot.getProject(this.virtualTsconfigPath); return project; } @@ -334,9 +389,22 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { return this.projectConfig; } - private createFsProxy(): Required< - Pick - > { + private createFsProxy(): tsFs.FileSystemCallbacks { + // optional chaining for supporting older version. + // For older version, undefined means using the default system callbacks. So this setup is type safe and also compatible with both older and newer versions. + + const serverFS = this.tsFsModule?.serverFS; + const defaultSys: tsFs.FileSystemCallbacks = { + fileExists: serverFS?.useOS, + directoryExists: serverFS?.useOS, + getAccessibleEntries: serverFS?.useOS, + stat: serverFS?.useOS, + realpath: serverFS?.useOS, + writeFile: serverFS?.useOS, + removeFile: serverFS?.useOS, + readFile: serverFS?.useOS + }; + const service = this; const kitFiles: Parameters[1] = { serverHooksPath: 'src/hooks.client', @@ -344,12 +412,19 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { universalHooksPath: 'src/hooks', paramsPath: 'src/params' }; + const useStableApi = this.useStableApi; return { + directoryExists: serverFS?.useOS, + stat: serverFS?.useOS, + realpath: serverFS?.useOS, + writeFile: serverFS?.useOS, + removeFile: serverFS?.useOS, getAccessibleEntries(directory: string) { const realFiles: string[] = []; const directories: string[] = []; const resultFiles: string[] = []; + const symlinks: string[] = []; try { const entries = fs.readdirSync(directory, { withFileTypes: true }); for (const entry of entries) { @@ -358,12 +433,16 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { } else if (entry.isDirectory()) { directories.push(entry.name); } else if (entry.isSymbolicLink()) { - const fullPath = path.join(directory, entry.name); - const stats = fs.statSync(fs.realpathSync(fullPath)); - if (stats.isFile()) { - realFiles.push(entry.name); - } else if (stats.isDirectory()) { - directories.push(entry.name); + if (useStableApi) { + symlinks.push(entry.name); + } else { + const fullPath = path.join(directory, entry.name); + const stats = fs.statSync(fs.realpathSync(fullPath)); + if (stats.isFile()) { + realFiles.push(entry.name); + } else if (stats.isDirectory()) { + directories.push(entry.name); + } } } } @@ -372,11 +451,12 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { } return { files: resultFiles, - directories + directories, + symlinks }; } catch (error) { Logger.error(`Error reading directory ${directory}:`, error); - return undefined; + return serverFS?.error; } }, readFile(path: string) { @@ -404,8 +484,7 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { return snapshot.getFullText(); } - // undefined to signal api to read from disk by itself - return undefined; + return serverFS?.useOS; }, fileExists(filePath: string) { const virtualFiles = service.virtualFiles; @@ -436,8 +515,7 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { } } - // undefined to signal api to check existence by itself - return undefined; + return serverFS?.useOS; } }; diff --git a/packages/language-server/src/plugins/typescript-go/types.ts b/packages/language-server/src/plugins/typescript-go/types.ts index 3dc0af7e9..3d76d8b3d 100644 --- a/packages/language-server/src/plugins/typescript-go/types.ts +++ b/packages/language-server/src/plugins/typescript-go/types.ts @@ -1,4 +1,5 @@ -import type tsAst from '@typescript/native-preview/unstable/ast' with { 'resolution-mode': 'import' }; -import type tsApiSync from '@typescript/native-preview/unstable/sync' with { 'resolution-mode': 'import' }; +import type tsAst from '@typescript/native/ast' with { 'resolution-mode': 'import' }; +import type tsApiSync from '@typescript/native/sync' with { 'resolution-mode': 'import' }; +import type tsFs from '@typescript/native/fs' with { 'resolution-mode': 'import' }; -export { tsAst, tsApiSync }; +export { tsAst, tsApiSync, tsFs }; diff --git a/packages/language-server/src/svelte-check.ts b/packages/language-server/src/svelte-check.ts index bb2eebee7..bf34ce1ad 100644 --- a/packages/language-server/src/svelte-check.ts +++ b/packages/language-server/src/svelte-check.ts @@ -25,7 +25,7 @@ import { isInGeneratedCode } from './plugins/typescript/features/utils'; import { mapAndFilterDiagnostics } from './plugins/typescript/features/DiagnosticsProvider'; import { convertRange, getDiagnosticTag, mapSeverity } from './plugins/typescript/utils'; import { groupBy, normalizePath, pathToUrl, urlToPath } from './utils'; -import { tsApiSync, tsAst } from './plugins/typescript-go/types'; +import { tsApiSync, tsAst, tsFs } from './plugins/typescript-go/types'; import { SvelteCheckTSGoDiagnosticsProvider } from './plugins/typescript-go/features/DiagnosticsProvider'; export function mapSvelteCheckDiagnostics( @@ -78,6 +78,8 @@ export interface SvelteCheckOptions { tsgo: { apiModule: unknown; astModule: unknown; + fsModule: unknown; + tsVersion: string; }; }; } @@ -146,16 +148,17 @@ export class SvelteCheck { if (shouldRegister('js') || options.tsconfig) { const workspaceUris = [pathToUrl(workspacePath)]; if (options.experimental?.tsgo && options.tsconfig) { - const { apiModule, astModule } = options.experimental.tsgo as { + const modules = options.experimental.tsgo as { apiModule: typeof tsApiSync; astModule: typeof tsAst; + fsModule: typeof tsFs; + tsVersion: string; }; - if (!apiModule.API || !('ScriptKind' in astModule)) { + if (!modules.apiModule.API || !('ScriptKind' in modules.astModule)) { throw new Error('Unsupported typescript-go version'); } this.tsGoDiagnosticsProvider = new SvelteCheckTSGoDiagnosticsProvider( - apiModule, - astModule, + modules, options.tsconfig, 'svelte-check', (filePath: string, text: string) => diff --git a/packages/language-server/test/plugins/typescript-go/features/diagnostics/index.test.ts b/packages/language-server/test/plugins/typescript-go/features/diagnostics/index.test.ts index ae4537d06..25ca06897 100644 --- a/packages/language-server/test/plugins/typescript-go/features/diagnostics/index.test.ts +++ b/packages/language-server/test/plugins/typescript-go/features/diagnostics/index.test.ts @@ -121,11 +121,20 @@ function setupService(dir: string) { if (providerPool.has(tsconfig)) { return; } - const syncApi = await import('@typescript/native-preview/unstable/sync'); - const tsAst = await import('@typescript/native-preview/unstable/ast'); + + const [syncApi, tsAst, tsFs, version] = await Promise.all([ + import('@typescript/native/sync'), + import('@typescript/native/ast'), + import('@typescript/native/fs'), + import('@typescript/native') + ]); const service = new SvelteCheckTSGoDiagnosticsProvider( - syncApi, - tsAst, + { + apiModule: syncApi, + astModule: tsAst, + fsModule: tsFs, + tsVersion: version.version + }, tsconfig, 'svelte2tsx', (filePath, content) => new Document(pathToUrl(filePath), content) diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/actions-animations-transitions-typechecks/expected_tsgo.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/actions-animations-transitions-typechecks/expected_tsgo.json index e93bdf567..0f868c944 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/actions-animations-transitions-typechecks/expected_tsgo.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/actions-animations-transitions-typechecks/expected_tsgo.json @@ -14,7 +14,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'HTMLParagraphElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, capture, and 54 more.", + "message": "Type 'HTMLParagraphElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, capture, and 55 more.", "code": 2740, "tags": [] } diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_4.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_4.json new file mode 100644 index 000000000..181f61e7f --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_4.json @@ -0,0 +1,98 @@ +[ + { + "range": { "start": { "line": 9, "character": 6 }, "end": { "line": 9, "character": 13 } }, + "severity": 4, + "source": "ts", + "message": "'element' is declared but its value is never read.", + "code": 6133, + "tags": [1] + }, + { + "range": { + "start": { "line": 18, "character": 2 }, + "end": { "line": 18, "character": 11 } + }, + "severity": 1, + "source": "ts", + "message": "Variable 'component' is used before being assigned.", + "code": 2454, + "tags": [] + }, + { + "range": { + "start": { "line": 40, "character": 16 }, + "end": { "line": 40, "character": 23 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'HTMLDivElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, capture, and 55 more.", + "code": 2740, + "tags": [] + }, + { + "range": { + "start": { "line": 41, "character": 34 }, + "end": { "line": 41, "character": 48 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n Types of property '$set' are incompatible.\n Type '(props: Partial<{ prop: boolean; }>) => void' is not assignable to type '(props: Partial<{ prop: string; }>) => void'.\n Types of parameters 'props' and 'props' are incompatible.\n Type 'Partial<{ prop: string; }>' is not assignable to type 'Partial<{ prop: boolean; }>'.\n Types of property 'prop' are incompatible.\n Type 'string | undefined' is not assignable to type 'boolean | undefined'.\n Type 'string' is not assignable to type 'boolean | undefined'.", + "code": 2322, + "tags": [] + }, + { + "range": { + "start": { "line": 42, "character": 35 }, + "end": { "line": 42, "character": 57 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'ComponentWithFunction1' is not assignable to type 'ComponentWithFunction2'.\n Types of property 'action' are incompatible.\n Type '(a: number) => string | number' is not assignable to type '() => string'.\n Target signature provides too few arguments. Expected 1 or more, but got 0.", + "code": 2322, + "tags": [] + }, + { + "range": { + "start": { "line": 43, "character": 1 }, + "end": { "line": 43, "character": 17 } + }, + "severity": 1, + "source": "ts", + "message": "Property 'prop' is missing in type '{}' but required in type '{ prop: boolean; }'.", + "code": 2741, + "tags": [] + }, + { + "range": { + "start": { "line": 43, "character": 46 }, + "end": { "line": 43, "character": 60 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n Types of property '$set' are incompatible.\n Type '(props: Partial<{ prop: boolean; }>) => void' is not assignable to type '(props: Partial<{ prop: string; }>) => void'.\n Types of parameters 'props' and 'props' are incompatible.\n Type 'Partial<{ prop: string; }>' is not assignable to type 'Partial<{ prop: boolean; }>'.\n Types of property 'prop' are incompatible.\n Type 'string | undefined' is not assignable to type 'boolean | undefined'.\n Type 'string' is not assignable to type 'boolean | undefined'.", + "code": 2322, + "tags": [] + }, + { + "range": { + "start": { "line": 46, "character": 45 }, + "end": { "line": 46, "character": 65 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'ComponentWithGeneric' is not assignable to type 'ComponentWithGeneric'.\n Types of property '$set' are incompatible.\n Type '(props: Partial<{ prop: boolean; }>) => void' is not assignable to type '(props: Partial<{ prop: string; }>) => void'.\n Types of parameters 'props' and 'props' are incompatible.\n Type 'Partial<{ prop: string; }>' is not assignable to type 'Partial<{ prop: boolean; }>'.\n Types of property 'prop' are incompatible.\n Type 'string | undefined' is not assignable to type 'boolean | undefined'.\n Type 'string' is not assignable to type 'boolean | undefined'.", + "code": 2322, + "tags": [] + }, + { + "range": { + "start": { "line": 47, "character": 1 }, + "end": { "line": 47, "character": 17 } + }, + "severity": 1, + "source": "ts", + "message": "Property 'prop' is missing in type '{}' but required in type '{ prop: boolean; }'.", + "code": 2741, + "tags": [] + } +] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expectedv2.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_5.json similarity index 71% rename from packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expectedv2.json rename to packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_5.json index 58b72cf39..1376ad95a 100644 --- a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expectedv2.json +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/bind-this/expected_tsgo_svelte_5.json @@ -25,7 +25,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'HTMLDivElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, capture, and 54 more.", + "message": "Type 'HTMLDivElement' is missing the following properties from type 'HTMLInputElement': accept, alt, autocomplete, capture, and 55 more.", "code": 2740, "tags": [] }, @@ -36,7 +36,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n Types of property '$set' are incompatible.\n Type '(props?: Partial<{ prop: boolean; }> | undefined) => void' is not assignable to type '(props?: Partial<{ prop: string; }> | undefined) => void'.\n Types of parameters 'props' and 'props' are incompatible.\n Type 'Partial<{ prop: string; }> | undefined' is not assignable to type 'Partial<{ prop: boolean; }> | undefined'.\n Type 'Partial<{ prop: string; }>' is not assignable to type 'Partial<{ prop: boolean; }>'.\n Types of property 'prop' are incompatible.\n Type 'string | undefined' is not assignable to type 'boolean | undefined'.\n Type 'string' is not assignable to type 'boolean | undefined'.", + "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n The types of '$$prop_def.prop' are incompatible between these types.\n Type 'boolean' is not assignable to type 'string'.", "code": 2322, "tags": [] }, @@ -58,8 +58,8 @@ }, "severity": 1, "source": "ts", - "message": "Property 'prop' is missing in type '{}' but required in type '{ prop: boolean; }'.", - "code": 2741, + "message": "Type '{}' is not assignable to type 'Properties<{ prop: boolean; }, any> | undefined'.", + "code": 2322, "tags": [] }, { @@ -69,7 +69,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'Component' is not assignable to type 'OtherComponent'.", + "message": "Type 'Component' is not assignable to type 'OtherComponent'.\n The types of '$$prop_def.prop' are incompatible between these types.\n Type 'boolean' is not assignable to type 'string'.", "code": 2322, "tags": [] }, @@ -80,7 +80,7 @@ }, "severity": 1, "source": "ts", - "message": "Type 'ComponentWithGeneric' is not assignable to type 'ComponentWithGeneric'.\n Type 'boolean' is not assignable to type 'string'.", + "message": "Type 'ComponentWithGeneric' is not assignable to type 'ComponentWithGeneric'.\n The types of '$$prop_def.prop' are incompatible between these types.\n Type 'boolean' is not assignable to type 'string'.", "code": 2322, "tags": [] }, @@ -91,8 +91,8 @@ }, "severity": 1, "source": "ts", - "message": "Property 'prop' is missing in type '{}' but required in type '{ prop: boolean; }'.", - "code": 2741, + "message": "Type '{}' is not assignable to type 'Properties<{ prop: boolean; }, any> | undefined'.", + "code": 2322, "tags": [] } ] diff --git a/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected_tsgo.json b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected_tsgo.json new file mode 100644 index 000000000..84630fc15 --- /dev/null +++ b/packages/language-server/test/plugins/typescript/features/diagnostics/fixtures/svelte-element/expected_tsgo.json @@ -0,0 +1,24 @@ +[ + { + "range": { + "start": { "line": 22, "character": 38 }, + "end": { "line": 22, "character": 51 } + }, + "severity": 1, + "source": "ts", + "message": "Type 'HTMLDivElement' is missing the following properties from type 'HTMLAnchorElement': charset, coords, download, name, and 21 more.", + "code": 2740, + "tags": [] + }, + { + "range": { + "start": { "line": 23, "character": 27 }, + "end": { "line": 23, "character": 38 } + }, + "severity": 1, + "source": "ts", + "message": "Object literal may only specify known properties, and '\"cellpadding\"' does not exist in type 'HTMLProps<\"div\", HTMLAttributes>'.", + "code": 2353, + "tags": [] + } +] diff --git a/packages/svelte-check/package.json b/packages/svelte-check/package.json index 084b0a65a..a66c99547 100644 --- a/packages/svelte-check/package.json +++ b/packages/svelte-check/package.json @@ -51,7 +51,7 @@ "@rollup/plugin-replace": "5.0.2", "@rollup/plugin-typescript": "^10.0.0", "@types/sade": "^1.7.2", - "@typescript/native-preview": "~7.0.0-dev.20260703.1", + "@typescript/native": "npm:typescript@7.0.2", "rollup": "3.7.5", "rollup-plugin-cleanup": "^3.2.0", "rollup-plugin-copy": "^3.4.0", diff --git a/packages/svelte-check/src/index.ts b/packages/svelte-check/src/index.ts index cd3f95f15..f4d9667c8 100644 --- a/packages/svelte-check/src/index.ts +++ b/packages/svelte-check/src/index.ts @@ -30,6 +30,7 @@ import { formatTsGoNotFoundError, tryLoadApi as tryLoadTsApi, tryLoadAst as tryLoadTsAst, + tryLoadFs as tryLoadTsFs, tryParseTsGoVersion } from './tsgo'; @@ -631,15 +632,20 @@ parseOptions(async (opts) => { } } - const apiModule = await tryLoadTsApi(opts.tsconfig, pkg); - const astModule = await tryLoadTsAst(opts.tsconfig, pkg); - if (!apiModule || !astModule) { + const [apiModule, astModule, fsModule] = await Promise.all([ + tryLoadTsApi(opts.tsconfig, pkg), + tryLoadTsAst(opts.tsconfig, pkg), + tryLoadTsFs(opts.tsconfig, pkg) + ]); + if (!apiModule || !astModule || !fsModule) { throw new Error( `Unsupported ${pkg.pkgJsonName} version. Please ensure you have the latest version installed.` + 'If the problem persists, please report an issue in https://github.com/sveltejs/language-tools/issues.' ); } - svelteCheckOptions.experimental = { tsgo: { apiModule, astModule } }; + + const fullVersion = pkg.major + '.' + pkg.minor + '.' + pkg.patch; + svelteCheckOptions.experimental = { tsgo: { apiModule, astModule, tsVersion: fullVersion, fsModule } }; } const useVirtualFiles = opts.incremental || opts.tsgo; diff --git a/packages/svelte-check/src/tsgo.ts b/packages/svelte-check/src/tsgo.ts index 4d2b5dab5..5efe55536 100644 --- a/packages/svelte-check/src/tsgo.ts +++ b/packages/svelte-check/src/tsgo.ts @@ -1,5 +1,6 @@ -import * as syncApi from '@typescript/native-preview/unstable/sync'; -import * as syncAst from '@typescript/native-preview/unstable/ast'; +import * as syncApi from '@typescript/native/unstable/sync'; +import * as syncAst from '@typescript/native/unstable/ast'; +import * as syncFs from '@typescript/native/unstable/fs'; import { pathToFileURL } from 'url'; interface PkgInfo { @@ -87,6 +88,17 @@ export async function tryLoadAst( ); } +export async function tryLoadFs( + tsconfigPath: string, + info: PkgInfo +): Promise { + return ( + (await tryImport(info.moduleName + '/unstable/fs', tsconfigPath)) ?? + (await tryImport(info.moduleName + '/fs', tsconfigPath)) + ); +} + + async function tryImport(moduleName: string, tsconfigPath: string): Promise { try { const modulePath = require.resolve(moduleName, { diff --git a/packages/svelte-check/test-sanity.js b/packages/svelte-check/test-sanity.js index 7043e5a7e..3037e6213 100644 --- a/packages/svelte-check/test-sanity.js +++ b/packages/svelte-check/test-sanity.js @@ -137,7 +137,7 @@ function testCrashedCompiler(name, compilerBody) { // inside the workspace, so a fake `@typescript/native-preview` in the workspace's // node_modules is picked up instead of the real one. const crashWorkspace = mkdtempSync(path.join(os.tmpdir(), 'svelte-check-crash-')); - const tsgoPkg = path.join(crashWorkspace, 'node_modules', '@typescript/native-preview'); + const tsgoPkg = path.join(crashWorkspace, 'node_modules', '@typescript/native'); mkdirSync(tsgoPkg, { recursive: true }); mkdirSync(path.join(crashWorkspace, 'src')); writeFileSync( @@ -154,9 +154,9 @@ function testCrashedCompiler(name, compilerBody) { writeFileSync( path.join(tsgoPkg, 'package.json'), JSON.stringify({ - name: '@typescript/native-preview', + name: 'typescript', version: '7.0.0', - bin: { tsgo: './fake-tsgo.js' } + bin: { tsc: './fake-tsgo.js' } }) ); writeFileSync(path.join(tsgoPkg, 'fake-tsgo.js'), compilerBody); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f964f9fe1..33eeebbe6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,9 +106,9 @@ importers: '@types/sinon': specifier: ^7.5.2 version: 7.5.2 - '@typescript/native-preview': - specifier: ~7.0.0-dev.20260703.1 - version: 7.0.0-dev.20260703.1 + '@typescript/native': + specifier: npm:typescript@7.1.0-beta + version: typescript@7.1.0-beta cross-env: specifier: ^7.0.2 version: 7.0.3 @@ -173,9 +173,9 @@ importers: '@types/sade': specifier: ^1.7.2 version: 1.7.4 - '@typescript/native-preview': - specifier: ~7.0.0-dev.20260703.1 - version: 7.0.0-dev.20260703.1 + '@typescript/native': + specifier: npm:typescript@7.0.2 + version: typescript@7.0.2 rollup: specifier: 3.7.5 version: 3.7.5 @@ -909,52 +909,251 @@ packages: '@types/vscode@1.78.0': resolution: {integrity: sha512-LJZIJpPvKJ0HVQDqfOy6W4sNKUBBwyDu1Bs8chHBZOe9MNuKTJtidgZ2bqjhmmWpUb0TIIqv47BFUcVmAsgaVA==} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-EwJEd6hfaHrrbSLat6+xX8fZiAvG+/Ae1gqvJEayTNdDbkrZxmeLS23YdjUmDMIOKI2wa7zXQDid8WtrvDfMTQ==} + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-aix-ppc64@7.1.0-beta': + resolution: {integrity: sha512-DXDG+jIWxBHGdoO70tcHON33rCnSzsEZj9P13oyf/r/KEGIo6awsdSNVNjAw0uMwEpqRu75IrgCcW58YcVkZHg==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-android-arm64@7.1.0-beta': + resolution: {integrity: sha512-UZx6PxoQavuvaVTrSf3aw0Oy/J/uJpRylipA0kzc038jMvZXh0UtE8vnQp20FqtdgD5bhXZ0aJrRJyoTSUO58Q==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [android] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [darwin] - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-tcS3gpivMq+BAiaupFqM5vuERykogJlfD4CjoxkSCksmmsKgWV96S2U/LjrKgll8R6/OEkg2VL2ycRG9+tIuHw==} + '@typescript/typescript-darwin-arm64@7.1.0-beta': + resolution: {integrity: sha512-q7mxblcyX0E7hXsY4k+Q6KWKK5mGmfVq+BDesdTgRVgjodk27aIxER77Zyj9+TgSTlCje8F7+JM6f6hl2BuNdw==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} engines: {node: '>=16.20.0'} cpu: [x64] os: [darwin] - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-m8IJTOneLXRtq6prLz8uuhp463kEt+AHV5Ceqp7G0o3eAvbKP059OwzK6WXCS5J0B3ZxX+BwBf9wDXSNidWJCw==} + '@typescript/typescript-darwin-x64@7.1.0-beta': + resolution: {integrity: sha512-D5EYqG5Wm/guw9+0j8+Mn1Jbr/gfS/VtFTuoH8PJtFbcqeDaQGMulc7SW8q51QG6Y3wGOGX3nbsTOw6fIKWWAA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-arm64@7.1.0-beta': + resolution: {integrity: sha512-9A0XX0tcnH9qPdolSKKzSjTb93dlB0UEcAJbHYEsrFX2fkFNSum9+dvkQQJ9vLc+7vxHetDPujq9Qe6wx+Xhow==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.1.0-beta': + resolution: {integrity: sha512-EDf/dBHfY0TxX3NmUTek0hbffeyZlh3+ls6WQW3ICB8vYxwYLFnzg7wkgEUvl9eRlpiJ/nmc2S8arPMzINJ7rg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm64@7.1.0-beta': + resolution: {integrity: sha512-hNqQBgQ5b5oGqN76QqbAU6CwYhJZ6iOcWc2kPTUs2OentgpxZktETziH6KIyRFJPaiBncognwn2ZLu3DNhHiWw==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [linux] - '@typescript/native-preview-linux-arm@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-nluwnKcdGo6laWWYtWF3zFUDfi7nNrcD5S/T5382fVmtKmNqIdzFm9ANgSSGAavuzfdu9YJLaVWpx72Oe40AEQ==} + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} engines: {node: '>=16.20.0'} cpu: [arm] os: [linux] - '@typescript/native-preview-linux-x64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-5ga94rso68kaxJUzaufDVhka1zPaSbPgNXaemQO8faPW0crvRIkbv0g8bpG4pdWMV0tTylmluDles4ZcAzOprg==} + '@typescript/typescript-linux-arm@7.1.0-beta': + resolution: {integrity: sha512-AvN9HmzOQh46G4312ooSgMHhbB7DtnLwg8D9mo324X49B7weMwtJrBG1MxT9IyI8kzDd7YRtW+1hWGun7WG7Qw==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-loong64@7.1.0-beta': + resolution: {integrity: sha512-xbUustlBrFflt2pNEyG5ye+d4WGPc/rfr2xK29MXeobPSw297JqwuKRrvbKM5o3fE/eUM/c+urVm6jQ3IaMVTw==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.1.0-beta': + resolution: {integrity: sha512-fS4/G7/0bXZ3NSq3nBMAXyg65I3tO4S7j08VNQ2g1aNC/qq79gE7Qne1BNjVsjMFfHBVBFjQYoTQCjmVU2iFlg==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.1.0-beta': + resolution: {integrity: sha512-0upCCxYPX8X6gOwkvfv+Ee7/ufyy7k97mTrGE0e5BxLlnUEa+w+rtgnv2dsKcxFdwdeZYVlZKCqgN/xCBV08+A==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.1.0-beta': + resolution: {integrity: sha512-0jKU9YRgOPRgiy5V/UWv37kB53PaTpIbwGCbbOMUPPAkrjVRNOIAJaz7Wa7s3H7mdDebX1LopUEPEJR+7Xa7zg==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-s390x@7.1.0-beta': + resolution: {integrity: sha512-j+d04s2kxaPQh6DLPb01sknAQfzsrdSZy15jBRHyLEZoaaQ19dVjbFRlkNVvYwUG7ZdP8+y5b/7RmPxdtHUKdQ==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} engines: {node: '>=16.20.0'} cpu: [x64] os: [linux] - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-YeRqOUuSyhbtryBSUE073OLpReIQXWJVyjP45gPLJ+0KAGvkd1VFz2FY1JEo++LyHoqXsGD2+qvdPpnTfSAIJg==} + '@typescript/typescript-linux-x64@7.1.0-beta': + resolution: {integrity: sha512-kcD51ihf+pnI5KT4uQQYG04OpwznaZYBlIQhDhl8fflFd27NktxXsUeguxZyvUMyWfum7IF2bBS6Jv7ox0AgFQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-arm64@7.1.0-beta': + resolution: {integrity: sha512-8W85YyoGK+rgGoSU9jJQUpELbrKcZcbdJk2jPNQ6UKDKI7ryPlPFTrV2jCE5RQuv4Tt96hMDTc33s4YfRrLFBA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.1.0-beta': + resolution: {integrity: sha512-iGsTE0ve2PG0AcyZinwAR0LnGEZhu/y4dceS0hZsYCaKdYETvQtvtlNWlmYKempsBr6C7Il7dMXHVk+VFm9u0g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-arm64@7.1.0-beta': + resolution: {integrity: sha512-Z2FERdHB9fAKI+KGqdWn04O7uNlnB+VYiEm6INE1aZuzzLNd3KBqQ6IpKUJF2ny4GigGU6nVu75XD9tAUODPng==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.1.0-beta': + resolution: {integrity: sha512-NVG3qeyCq/rJEOhaRjR3LsWgjrjo5vJW25omVLeHAVnpKIG4pE4cenwwKGR06DiJ1s0QTOymcJeKXMEpsiNBVg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-sunos-x64@7.1.0-beta': + resolution: {integrity: sha512-ovAdoWXEn2B5/fyWG69pLU3FWmQwPWOjQV5TFbcxtpnOv+R3g8ySGHl1NYRq7Lb/GYdFDvaGcZ+SiU7iKuiMsA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-arm64@7.1.0-beta': + resolution: {integrity: sha512-lJbo71IEOfL7ZZIZnArRaOLqjn9BAfoSzyUQn0aSjfSpDZL4ru0afUsdBfo6PQEjD6ssdmi0n/RwaPADX6bsvQ==} engines: {node: '>=16.20.0'} cpu: [arm64] os: [win32] - '@typescript/native-preview-win32-x64@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-WYNcbTaxCPgiDLrL2aPJ3BJA05nJU8DK0fUFGkGAER0oM+KcJcQUBeUkXg/7A4HBTNYcj7zIxqNgkJU1TRa/Kw==} + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} engines: {node: '>=16.20.0'} cpu: [x64] os: [win32] - '@typescript/native-preview@7.0.0-dev.20260703.1': - resolution: {integrity: sha512-qyEHkEeRWCSGLa6a8oArnMPdn3Vcl1AZj8YHLO7lK0VjEEF/YJfz1FvxmpEeuhy0ZDfvJ7GtgXbvbjcU3zpPjQ==} + '@typescript/typescript-win32-x64@7.1.0-beta': + resolution: {integrity: sha512-UKcHvbybY2tDTvFW2b1vwiAvDlIRooo69lh8CXWVhOQejcvpM5+IgbiFW9EIwR5Wi5X/v+BdN7gdWbigBuJ3rw==} engines: {node: '>=16.20.0'} - hasBin: true + cpu: [x64] + os: [win32] '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} @@ -2030,6 +2229,16 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + typescript@7.1.0-beta: + resolution: {integrity: sha512-cjWjZAJDsmZzsNC5GwHNlW0YPM65jZa5oR0KyQcYX3KSVIfTvtBq//vewISyatKk4OLi5grZjHhIVE9fdrw1UQ==} + engines: {node: '>=16.20.0'} + hasBin: true + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -2757,36 +2966,128 @@ snapshots: '@types/vscode@1.78.0': {} - '@typescript/native-preview-darwin-arm64@7.0.0-dev.20260703.1': + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@typescript/native-preview-darwin-x64@7.0.0-dev.20260703.1': + '@typescript/typescript-aix-ppc64@7.1.0-beta': optional: true - '@typescript/native-preview-linux-arm64@7.0.0-dev.20260703.1': + '@typescript/typescript-android-arm64@7.1.0-beta': optional: true - '@typescript/native-preview-linux-arm@7.0.0-dev.20260703.1': + '@typescript/typescript-darwin-arm64@7.0.2': optional: true - '@typescript/native-preview-linux-x64@7.0.0-dev.20260703.1': + '@typescript/typescript-darwin-arm64@7.1.0-beta': optional: true - '@typescript/native-preview-win32-arm64@7.0.0-dev.20260703.1': + '@typescript/typescript-darwin-x64@7.0.2': optional: true - '@typescript/native-preview-win32-x64@7.0.0-dev.20260703.1': + '@typescript/typescript-darwin-x64@7.1.0-beta': optional: true - '@typescript/native-preview@7.0.0-dev.20260703.1': - optionalDependencies: - '@typescript/native-preview-darwin-arm64': 7.0.0-dev.20260703.1 - '@typescript/native-preview-darwin-x64': 7.0.0-dev.20260703.1 - '@typescript/native-preview-linux-arm': 7.0.0-dev.20260703.1 - '@typescript/native-preview-linux-arm64': 7.0.0-dev.20260703.1 - '@typescript/native-preview-linux-x64': 7.0.0-dev.20260703.1 - '@typescript/native-preview-win32-arm64': 7.0.0-dev.20260703.1 - '@typescript/native-preview-win32-x64': 7.0.0-dev.20260703.1 + '@typescript/typescript-freebsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-arm64@7.1.0-beta': + optional: true + + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true + + '@typescript/typescript-freebsd-x64@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-arm64@7.0.2': + optional: true + + '@typescript/typescript-linux-arm64@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-arm@7.0.2': + optional: true + + '@typescript/typescript-linux-arm@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-loong64@7.0.2': + optional: true + + '@typescript/typescript-linux-loong64@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-mips64el@7.0.2': + optional: true + + '@typescript/typescript-linux-mips64el@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-ppc64@7.0.2': + optional: true + + '@typescript/typescript-linux-ppc64@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-riscv64@7.0.2': + optional: true + + '@typescript/typescript-linux-riscv64@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-s390x@7.0.2': + optional: true + + '@typescript/typescript-linux-s390x@7.1.0-beta': + optional: true + + '@typescript/typescript-linux-x64@7.0.2': + optional: true + + '@typescript/typescript-linux-x64@7.1.0-beta': + optional: true + + '@typescript/typescript-netbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-arm64@7.1.0-beta': + optional: true + + '@typescript/typescript-netbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-netbsd-x64@7.1.0-beta': + optional: true + + '@typescript/typescript-openbsd-arm64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-arm64@7.1.0-beta': + optional: true + + '@typescript/typescript-openbsd-x64@7.0.2': + optional: true + + '@typescript/typescript-openbsd-x64@7.1.0-beta': + optional: true + + '@typescript/typescript-sunos-x64@7.0.2': + optional: true + + '@typescript/typescript-sunos-x64@7.1.0-beta': + optional: true + + '@typescript/typescript-win32-arm64@7.0.2': + optional: true + + '@typescript/typescript-win32-arm64@7.1.0-beta': + optional: true + + '@typescript/typescript-win32-x64@7.0.2': + optional: true + + '@typescript/typescript-win32-x64@7.1.0-beta': + optional: true '@vitest/expect@3.2.4': dependencies: @@ -3850,6 +4151,53 @@ snapshots: typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + typescript@7.1.0-beta: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.1.0-beta + '@typescript/typescript-android-arm64': 7.1.0-beta + '@typescript/typescript-darwin-arm64': 7.1.0-beta + '@typescript/typescript-darwin-x64': 7.1.0-beta + '@typescript/typescript-freebsd-arm64': 7.1.0-beta + '@typescript/typescript-freebsd-x64': 7.1.0-beta + '@typescript/typescript-linux-arm': 7.1.0-beta + '@typescript/typescript-linux-arm64': 7.1.0-beta + '@typescript/typescript-linux-loong64': 7.1.0-beta + '@typescript/typescript-linux-mips64el': 7.1.0-beta + '@typescript/typescript-linux-ppc64': 7.1.0-beta + '@typescript/typescript-linux-riscv64': 7.1.0-beta + '@typescript/typescript-linux-s390x': 7.1.0-beta + '@typescript/typescript-linux-x64': 7.1.0-beta + '@typescript/typescript-netbsd-arm64': 7.1.0-beta + '@typescript/typescript-netbsd-x64': 7.1.0-beta + '@typescript/typescript-openbsd-arm64': 7.1.0-beta + '@typescript/typescript-openbsd-x64': 7.1.0-beta + '@typescript/typescript-sunos-x64': 7.1.0-beta + '@typescript/typescript-win32-arm64': 7.1.0-beta + '@typescript/typescript-win32-x64': 7.1.0-beta + undici-types@5.26.5: {} unist-util-stringify-position@3.0.3: From 4a201f22e1589dbbf3a3209ed5fee7c0a21808ee Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Thu, 22 Oct 2026 10:26:33 +0800 Subject: [PATCH 2/5] ban 7.1 nightly before beta --- packages/svelte-check/src/index.ts | 12 ++++++++++- packages/svelte-check/src/tsgo.ts | 32 ++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/packages/svelte-check/src/index.ts b/packages/svelte-check/src/index.ts index f4d9667c8..69f9d5e28 100644 --- a/packages/svelte-check/src/index.ts +++ b/packages/svelte-check/src/index.ts @@ -630,6 +630,14 @@ parseOptions(async (opts) => { minPre7_0Nightly ); } + } else if (pkg.major === 7 && pkg.minor === 1 && pkg.preRelease?.includes('dev')) { + const minPre7_1Nightly = 'dev.20261021.1'; + if (pkg.preRelease.localeCompare(minPre7_1Nightly) < 0) { + throw new Error( + 'Unsupported TypeScript 7.1 version. Please upgrade to at least 7.1.0-beta or 7.1.0-' + + minPre7_1Nightly + ); + } } const [apiModule, astModule, fsModule] = await Promise.all([ @@ -645,7 +653,9 @@ parseOptions(async (opts) => { } const fullVersion = pkg.major + '.' + pkg.minor + '.' + pkg.patch; - svelteCheckOptions.experimental = { tsgo: { apiModule, astModule, tsVersion: fullVersion, fsModule } }; + svelteCheckOptions.experimental = { + tsgo: { apiModule, astModule, tsVersion: fullVersion, fsModule } + }; } const useVirtualFiles = opts.incremental || opts.tsgo; diff --git a/packages/svelte-check/src/tsgo.ts b/packages/svelte-check/src/tsgo.ts index 5efe55536..db6a29ffb 100644 --- a/packages/svelte-check/src/tsgo.ts +++ b/packages/svelte-check/src/tsgo.ts @@ -72,32 +72,34 @@ export async function tryLoadApi( tsconfigPath: string, info: PkgInfo ): Promise { - return ( - (await tryImport(info.moduleName + '/unstable/sync', tsconfigPath)) ?? - (await tryImport(info.moduleName + '/sync', tsconfigPath)) - ); + if (shouldLoadStableApi(info)) { + return await tryImport(info.moduleName + '/sync', tsconfigPath); + } + + return await tryImport(info.moduleName + '/unstable/sync', tsconfigPath); } export async function tryLoadAst( tsconfigPath: string, info: PkgInfo ): Promise { - return ( - (await tryImport(info.moduleName + '/unstable/ast', tsconfigPath)) ?? - (await tryImport(info.moduleName + '/ast', tsconfigPath)) - ); + if (shouldLoadStableApi(info)) { + return await tryImport(info.moduleName + '/ast', tsconfigPath); + } + + return await tryImport(info.moduleName + '/unstable/ast', tsconfigPath); } export async function tryLoadFs( tsconfigPath: string, info: PkgInfo ): Promise { - return ( - (await tryImport(info.moduleName + '/unstable/fs', tsconfigPath)) ?? - (await tryImport(info.moduleName + '/fs', tsconfigPath)) - ); -} + if (shouldLoadStableApi(info)) { + return await tryImport(info.moduleName + '/fs', tsconfigPath); + } + return await tryImport(info.moduleName + '/unstable/fs', tsconfigPath); +} async function tryImport(moduleName: string, tsconfigPath: string): Promise { try { @@ -109,3 +111,7 @@ async function tryImport(moduleName: string, tsconfigPath: string): Promise 7 || (pkg.major === 7 && pkg.minor >= 1); +} From 4704098095f56de3c835a44e1387748e2b3628cb Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Thu, 22 Oct 2026 10:27:26 +0800 Subject: [PATCH 3/5] tweak content mapper error message --- packages/language-server/src/svelte-check.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/language-server/src/svelte-check.ts b/packages/language-server/src/svelte-check.ts index bf34ce1ad..8a49042b2 100644 --- a/packages/language-server/src/svelte-check.ts +++ b/packages/language-server/src/svelte-check.ts @@ -482,6 +482,13 @@ export class SvelteCheck { const configFileParsingDiagnosticsLength = allTsDiagnostics?.length ?? 0; allTsDiagnostics = allTsDiagnostics.concat(project.program.getSyntacticDiagnostics()); + const contentMapperDiagnostic = allTsDiagnostics.find((v) => v.code === 18068); + if (contentMapperDiagnostic) { + contentMapperDiagnostic.text = 'Content mappers are not yet supported'; + return this.tsGoDiagnosticsProvider.mapAndFilterDiagnostics(project, [ + contentMapperDiagnostic + ]); + } if (allTsDiagnostics.length == configFileParsingDiagnosticsLength) { if ( From c5e6def898249622f8a8c898dbc8d99b7099ccc3 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Sat, 24 Oct 2026 10:09:54 +0800 Subject: [PATCH 4/5] fix getAccessibleEntries proxy for symlink --- .../features/DiagnosticsProvider.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts index 5f7a2ce54..ff8c6a4f5 100644 --- a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts +++ b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts @@ -424,6 +424,7 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { const realFiles: string[] = []; const directories: string[] = []; const resultFiles: string[] = []; + /**Names from `files` or `directories` that are symbolic links. */ const symlinks: string[] = []; try { const entries = fs.readdirSync(directory, { withFileTypes: true }); @@ -433,17 +434,14 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { } else if (entry.isDirectory()) { directories.push(entry.name); } else if (entry.isSymbolicLink()) { - if (useStableApi) { - symlinks.push(entry.name); - } else { - const fullPath = path.join(directory, entry.name); - const stats = fs.statSync(fs.realpathSync(fullPath)); - if (stats.isFile()) { - realFiles.push(entry.name); - } else if (stats.isDirectory()) { - directories.push(entry.name); - } + const fullPath = path.join(directory, entry.name); + const stats = fs.statSync(fs.realpathSync(fullPath)); + if (stats.isFile()) { + realFiles.push(entry.name); + } else if (stats.isDirectory()) { + directories.push(entry.name); } + symlinks.push(entry.name); } } for (const file of realFiles) { From 6c45598fb1c23c3750129b5f7170b1ecf541c7a1 Mon Sep 17 00:00:00 2001 From: "Lyu, Wei Da" Date: Thu, 29 Oct 2026 10:25:00 +0800 Subject: [PATCH 5/5] remove unused variable --- .../src/plugins/typescript-go/features/DiagnosticsProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts index ff8c6a4f5..ed65962fa 100644 --- a/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts +++ b/packages/language-server/src/plugins/typescript-go/features/DiagnosticsProvider.ts @@ -412,7 +412,6 @@ export class SvelteCheckTSGoDiagnosticsProvider implements DiagnosticsProvider { universalHooksPath: 'src/hooks', paramsPath: 'src/params' }; - const useStableApi = this.useStableApi; return { directoryExists: serverFS?.useOS,