Repository navigation
v4: move to TypeScript 7, framework support via content mappers - #103
Open
johnsoncodehk wants to merge 22 commits into
Open
johnsoncodehk wants to merge 22 commits into
johnsoncodehk wants to merge 22 commits into
Conversation
- @tsslint/cli now depends on typescript-native-bridge (pinned 6.0.3-bridge.15.tsgo.7.0.2) instead of the typescript peer dep; type checking runs on the TS 7 (tsgo) engine - Remove --vue-project/--vue-vine-project/--mdx-project/--astro-project/ --ts-macro-project flags and the Volar language plugin wiring (@volar/language-core, @volar/language-hub, @volar/typescript) - Meta-framework support will be provided by the TS 7.1 content mapper (tsconfig contentMappers) once TNB rebases onto tsgo 7.1 - Remove fixtures/meta-frameworks and untracked tsgo/relay experiments
The file was deleted with the Volar wiring; the hardcoded corpus list in packages/compat-eslint/test/bench/dogfood-corpus.ts still referenced it, failing lazy-estree.test.js with ENOENT in CI.
…lumbing - packages/cli now pins typescript-native-bridge 6.0.3-bridge.16.tsgo.7.0.2 - remove the languages parameter from the cache layer (dead since the Volar removal); the cache key no longer carries it, which also invalidates existing caches
- README: real framework-support section (tsconfig contentMappers), updated requirements (bundled engine, no typescript pin, musl unsupported) - docs/migration-v4.md: breaking changes, flag -> contentMappers mapping, engine behavior notes, editor status, availability gates
TypeScript 7 has no tsserver plugin API, so @tsslint/typescript-plugin and the VS Code extension built on it cannot work.
- Build the workspace with typescript@7.1.0-beta (module nodenext,
Node >= 22.12 for require(esm)); drop typescript-native-bridge.
- @tsslint/types: SourceFile from typescript/ast, Program/Checker/
DiagnosticCategory from typescript/sync. RuleContext gains `checker`
(TS7 programs have no getTypeChecker); LinterContext is
{ typescript, getProgram }.
- @tsslint/core: lint() takes { program, checker, file } instead of a
file name resolved through a LanguageService.
- Add tools/estree-oracle, a private test-only package pinning
typescript@6 + typescript-eslint as the parity reference.
- Port core tests to real TS7 projects; drop the BuilderProgram POC.
tsl and tslint are built on the TypeScript 5/6 API and cannot run on TS7. The eslint, ignore, category and diagnostics plugins now use typescript/ast and typescript/sync.
- lazy-estree / tokens / ts-ast-scan read typescript/ast. TS7 shape differences are handled in lib/ts.ts helpers: postfixToken for ?/!, ModuleDeclaration.keyword, phaseModifier for type-only imports, heritage clauses parsed as TypeReference, synthesized (Reparsed) nodes, nameless array-binding holes, EndOfFile/JSDoc kinds. - Scope analysis uses @typescript-eslint/scope-manager's analyze(), built lazily on first scopeManager read, replacing TsScopeManager. - parserServices type queries go through the project checker. - Parity tests compare against typescript-estree running on its own TypeScript 6 copy (tools/estree-oracle), bridged by node ranges. Tests depending on @typescript-eslint/eslint-plugin or the vendored scope-manager suite are removed: typescript-eslint cannot load TS7. - dogfood: register all rules before the first file is linted, so the shared traversal sees every rule (previously only the first one ran).
- lint through typescript/sync snapshots; project file names come from the configured project so content-mapped files (e.g. .vue) are included - replace the BuilderProgram incremental state with a program fingerprint (cache format v3) - map diagnostics back to original files via SourceFile.spanMap; drop diagnostics that only cover generated code - apply --fix only when every edit of a fix maps exactly - render with the TS7 formatDiagnosticsWithColorAndContext
Owner
Author
|
/release alpha 4.0.0 |
Contributor
|
Alpha release failed, see https://github.com/johnsoncodehk/tsslint/actions/runs/39767990607 |
Owner
Author
|
/release alpha 4.0.0 |
Contributor
|
Alpha release failed, see https://github.com/johnsoncodehk/tsslint/actions/runs/39770287974 |
Owner
Author
|
/release alpha 4.0.0 |
Contributor
|
Alpha release failed, see https://github.com/johnsoncodehk/tsslint/actions/runs/39771220489 |
Owner
Author
|
/release alpha 4.0.0 |
Contributor
|
Published |
Record the version published from f7d6918 by release run 39772141598, so the next `prerelease` release is 4.0.0-alpha.1. Only workspace specifiers change in pnpm-lock.yaml.
- Every package that loads `typescript/sync` / `typescript/ast` now depends
on typescript 7.1.0-beta instead of peering on it. TSSLint's checker is
its own engine; as a peer, pnpm resolved it to a host project's TS 6 and
`require('typescript/sync')` failed.
- @tsslint/config and @tsslint/compat-eslint declare an optional eslint
peer (>=9.39.0 <10.0.0). importESLintRules() loads core rules from
`node_modules/eslint/lib/rules`, and both packages expose ESLint types.
- @tsslint/config peers on @tsslint/compat-eslint via `workspace:*`, so
the published range always matches the release (it was `^3.0.0`).
…kind scans
ParenthesizedExpression, ParenthesizedType and ComputedPropertyName are
pass-through in convertChildInner: materialise returns the inner ESTree.
The scan relied on the child's target equalling the parent's to skip the
re-entry, but when the inner is a wrapper head (`(a?.b)` ->
ChainExpression, `(typeof import('x'))` -> TSTypeQuery) the parens level
expands the chain and leaves its tail as parentTarget, so the child's
visit entered the same chain again. In CPA and wildcard mode every
listener on those nodes fired twice (three times under `((a?.b))`), e.g.
no-non-null-asserted-optional-chain reported `(a?.b)!` twice.
The three kinds now join the structural pass-through list and recurse
with the parent's target unchanged.
…ession typescript-estree treats a non-null assertion that ends an optional chain (`a?.b!`, `a?.()!`, `a?.b.c!`, `a?.b!!`) as the chain's outermost link and wraps it in ChainExpression. The lazy converter only wrapped Member/CallExpression, so these produced a bare TSNonNullExpression and rules keyed on `ChainExpression > TSNonNullExpression` - notably no-non-null-asserted-optional-chain - silently missed them. isOutermostOptionalChain now accepts NonNullExpression (the ts-ast-scan ChainExpression predicate shares it), and TSNonNullExpression goes through wrapChainIfNeeded like the other links. Tests: lazy-estree-review-bugs compares 13 chain/non-null shapes with typescript-estree, plus parent links, bottom-up materialise and dispatch order for `a?.b!`; compat-pipeline runs the real no-non-null-asserted-optional-chain rule and requires the same reports as ESLint on typescript-eslint's parser. The estree-oracle test package now carries @typescript-eslint/eslint-plugin for that.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
TSSLint v4 runs lint rules on TypeScript 7's checker (tsgo) and removes the Volar-based framework support. Framework files come back through TypeScript's own content mapper (tsconfig
contentMappers) instead of per-framework CLI flags, so the tsconfig is the single source of truth. This PR is the first milestone: the CLI engine swap and the Volar removal.Quick start
tsslint --project tsconfig.json # no --vue-project etc., no typescript install needed for lintingBreaking changes
@tsslint/clibundles its own engine. It depends ontypescript-native-bridge(exact-pinned6.0.3-bridge.16.tsgo.7.0.2) instead of atypescriptpeer dependency. Diagnostics come from the tsgo 7.0.2 checker and can differ from TS 6 in edge cases.--vue-project,--vue-vine-project,--mdx-project,--astro-projectand--ts-macro-projectare removed, together with@volar/language-core,@volar/language-huband@volar/typescript. DeclarecontentMappersin the tsconfig instead; there is no replacement flag.languages.Remaining work
tsslint
spanMap, fixes offered only on Exact / Verbatim spans.typescript-native-bridgeto the TypeScript 7.1 API (typescript/async,typescript/ast), so TSSLint no longer depends on any TypeScript 5/6 API surface.@tsslint/typescript-pluginand the VS Code extension on the TypeScript 7 LSP extension points (LSP middleware, content mapper registration). Until then editor diagnostics for framework files keep the v3 setup.Done
Engine
@tsslint/cliruns ontypescript-native-bridge, a drop-in for the classictypescriptAPI surface backed by tsgo;require.resolve('typescript')points at the bridge.Volar removal
packages/cli/lib/languagePlugins.tsandfixtures/meta-frameworks.languagesplumbing left in the cache layer is removed.Docs
docs/migration-v4.md: breaking changes, flag →contentMappersmapping, engine behavior, editor status and availability.typescriptpin, musl unsupported).Tests
npm run linton the repo itself: 59 passed.Notes
typescript-native-bridgeneeds Node ≥ 20.19, below the CLI's existing 22.6 requirement.@tsslint/coretypings are declared against stocktypescript, so cross-package boundaries use type-only casts (ts as unknown as typeof import('typescript')); the runtime object is the same.pnpm run build && npm run lintReferences
microsoft/TypeScript)docs/migration-v4.md