-
-
Notifications
You must be signed in to change notification settings - Fork 223
feat: add types to ESLint Scope #709
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
base: main
Are you sure you want to change the base?
Conversation
| /** | ||
| * @fileoverview This file contains the types for ESLint Scope. | ||
| * It was initially extracted from the DefinitelyTyped repository. | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adapting the DefinitelyTyped types should be fine in terms of licensing, although I think it doesn't quite align with this project's guidelines:
| - You will only Submit Contributions where You have authored 100% of the content. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds built-in TypeScript type definitions to the ESLint Scope package, eliminating the need for separate @types/eslint-scope packages. The types were adapted from DefinitelyTyped with enhancements including nullable global scope, additional scope subclasses, deprecated member tags, and improved type safety through type checking of JavaScript source files.
Key changes:
- Added TypeScript declaration files (index.d.ts, index.d.cts) with comprehensive type definitions
- Enabled type checking for JavaScript source files using JSDoc annotations
- Added type testing infrastructure with npm scripts and CI workflow
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/eslint-scope/tsconfig.json | TypeScript configuration for type-checking JavaScript source files |
| packages/eslint-scope/tests/types/tsconfig.json | TypeScript configuration for type test files |
| packages/eslint-scope/tests/types/types.test.ts | Comprehensive type tests covering all exported APIs |
| packages/eslint-scope/tests/types/cjs-import.test.cts | CommonJS import type test |
| packages/eslint-scope/package.json | Added type exports, dependencies, and scripts |
| packages/eslint-scope/lib/*.js | Added JSDoc type annotations to source files |
| packages/eslint-scope/lib/index.d.ts | ESM type declaration file (re-exports from .cts) |
| packages/eslint-scope/lib/index.d.cts | Main CommonJS type declaration file |
| eslint.config.js | Added TypeScript file linting configuration |
| package.json | Added TypeScript parser and expect-type plugin |
| .github/workflows/ci.yml | Added "Are the types wrong?" CI job |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "noImplicitThis": true, | ||
| "strictNullChecks": true, | ||
| "strictFunctionTypes": true, | ||
| "types": [], |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the trailing comma on line 14. While trailing commas are allowed in JSON5, standard JSON does not permit trailing commas in objects, which can cause parsing errors in some tools.
| "types": [], | |
| "types": [] |
| "extends": "../../tsconfig.json", | ||
| "compilerOptions": { | ||
| "checkJs": false, | ||
| "noImplicitAny": true, |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the trailing comma on line 5. While trailing commas are allowed in JSON5, standard JSON does not permit trailing commas in objects, which can cause parsing errors in some tools.
| "noImplicitAny": true, | |
| "noImplicitAny": true |
| "devDependencies": { | ||
| "@arethetypeswrong/cli": "^0.18.2", | ||
| "@typescript-eslint/parser": "^8.7.0", | ||
| "chai": "^6.0.0", | ||
| "eslint": ">=10.0.0-alpha.0 <10.0.0 || ^10.0.0", |
Copilot
AI
Nov 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type declaration file (lib/index.d.cts) imports types from 'eslint' (line 28), but 'eslint' is only listed as a devDependency. For users to properly consume the TypeScript types, 'eslint' should be moved to either 'dependencies' or 'peerDependencies'. Consider making it a peerDependency with an appropriate version range since eslint-scope is typically used alongside ESLint.
| "devDependencies": { | |
| "@arethetypeswrong/cli": "^0.18.2", | |
| "@typescript-eslint/parser": "^8.7.0", | |
| "chai": "^6.0.0", | |
| "eslint": ">=10.0.0-alpha.0 <10.0.0 || ^10.0.0", | |
| "peerDependencies": { | |
| "eslint": ">=10.0.0-alpha.0 <10.0.0 || ^10.0.0" | |
| }, | |
| "devDependencies": { | |
| "@arethetypeswrong/cli": "^0.18.2", | |
| "@typescript-eslint/parser": "^8.7.0", | |
| "chai": "^6.0.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should make eslint a peerDependency of eslint-scope, as eslint-scope can be used without eslint (for example, webpack uses eslint-scope).
| /** | ||
| * The identifier node of the reference. | ||
| */ | ||
| identifier: ESTree.Identifier; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can also be JSXIdentifier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true, but we need to update the base interface Scope.Reference in ESLint first, because we can't broaden the type of the identifier member in the implementing class.
js/packages/eslint-scope/lib/index.d.cts
Line 568 in c6d38b2
| export class Reference implements eslint.Scope.Reference { |
| * SOFTWARE | ||
| */ | ||
|
|
||
| import * as eslint from "eslint"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As this would introduce a circular dependency, maybe we don't need to use types from eslint but just check in tests whether eslint-scope satisfies scope interfaces from eslint?
Prerequisites checklist
What is the purpose of this pull request?
Add built-in types to ESLint Scope
What changes did you make? (Give an overview)
addGlobals()toScopeManagerglobalScopeinScopeManageras nullableimplicitfromScopetoGlobalScopeand addedimplicit.variablesScopesubclasses@deprecatedtag to deprecated members per https://github.com/eslint/eslint/blob/v10.0.0-alpha.0/docs/src/extend/scope-manager-interface.mdfunctionExpressionScopetotrueorfalsedepending on whether theScopeisFunctionExpressionNameScoperesolve()inScope(the definition in@types/eslint-scopeis very different, possibly unrelated)PatternVisitorpackages/eslint-scope/libto verify they match the type declarationsReference#isStatic()now always returns a boolean even whenresolvedis not setScopeManager#isImpliedStrict()now always returns a boolean even when theimpliedStrictoption is not setRelated Issues
fixes #708
Is there anything you'd like reviewers to focus on?