diff --git a/.eslintrc.json b/.eslintrc.json index 819d042c25b16..a6d1b6345b452 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -105,9 +105,14 @@ } } ], - - // Todo: For each of these, investigate whether we want to enable them ✨ - "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + // Ignore: (solely underscores | starting with exactly one underscore) + "argsIgnorePattern": "^(_+$|_[^_])", + "varsIgnorePattern": "^(_+$|_[^_])" + } + ], // Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820 "@typescript-eslint/prefer-optional-chain": "off", diff --git a/scripts/eslint/rules/argument-trivia.cjs b/scripts/eslint/rules/argument-trivia.cjs index 8a6d1a8f112ca..423da853e212a 100644 --- a/scripts/eslint/rules/argument-trivia.cjs +++ b/scripts/eslint/rules/argument-trivia.cjs @@ -1,7 +1,11 @@ -const { AST_NODE_TYPES, TSESTree, ESLintUtils } = require("@typescript-eslint/utils"); +const { AST_NODE_TYPES, ESLintUtils } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); const ts = require("typescript"); +/** + * @typedef {import("@typescript-eslint/utils").TSESTree.CallExpression | import("@typescript-eslint/utils").TSESTree.NewExpression} CallOrNewExpression + */ + const unset = Symbol(); /** * @template T @@ -42,7 +46,7 @@ module.exports = createRule({ /** @type {(name: string) => boolean} */ const isSetOrAssert = name => name.startsWith("set") || name.startsWith("assert"); - /** @type {(node: TSESTree.Node) => boolean} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */ const isTrivia = node => { if (node.type === AST_NODE_TYPES.Identifier) { return node.name === "undefined"; @@ -56,7 +60,7 @@ module.exports = createRule({ return false; }; - /** @type {(node: TSESTree.CallExpression | TSESTree.NewExpression) => boolean} */ + /** @type {(node: CallOrNewExpression) => boolean} */ const shouldIgnoreCalledExpression = node => { if (node.callee && node.callee.type === AST_NODE_TYPES.MemberExpression) { const methodName = node.callee.property.type === AST_NODE_TYPES.Identifier @@ -97,7 +101,7 @@ module.exports = createRule({ return false; }; - /** @type {(node: TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */ const checkArg = (node, i, getSignature) => { if (!isTrivia(node)) { return; @@ -119,7 +123,7 @@ module.exports = createRule({ }); const comments = sourceCode.getCommentsBefore(node); - /** @type {TSESTree.Comment | undefined} */ + /** @type {import("@typescript-eslint/utils").TSESTree.Comment | undefined} */ const comment = comments[comments.length - 1]; if (!comment || comment.type !== "Block") { @@ -170,7 +174,7 @@ module.exports = createRule({ } }; - /** @type {(node: TSESTree.CallExpression | TSESTree.NewExpression) => void} */ + /** @type {(node: CallOrNewExpression) => void} */ const checkArgumentTrivia = node => { if (shouldIgnoreCalledExpression(node)) { return; diff --git a/scripts/eslint/rules/debug-assert.cjs b/scripts/eslint/rules/debug-assert.cjs index 31a735c246889..ca3a4263d7d60 100644 --- a/scripts/eslint/rules/debug-assert.cjs +++ b/scripts/eslint/rules/debug-assert.cjs @@ -1,4 +1,4 @@ -const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils"); +const { AST_NODE_TYPES } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); module.exports = createRule({ @@ -17,14 +17,14 @@ module.exports = createRule({ defaultOptions: [], create(context) { - /** @type {(node: TSESTree.Node) => boolean} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */ const isArrowFunction = node => node.type === AST_NODE_TYPES.ArrowFunctionExpression; - /** @type {(node: TSESTree.Node) => boolean} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */ const isStringLiteral = node => ( (node.type === AST_NODE_TYPES.Literal && typeof node.value === "string") || node.type === AST_NODE_TYPES.TemplateLiteral ); - /** @type {(node: TSESTree.MemberExpression) => boolean} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.MemberExpression) => boolean} */ const isDebugAssert = node => ( node.object.type === AST_NODE_TYPES.Identifier && node.object.name === "Debug" @@ -32,7 +32,7 @@ module.exports = createRule({ && node.property.name === "assert" ); - /** @type {(node: TSESTree.CallExpression) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.CallExpression) => void} */ const checkDebugAssert = node => { const args = node.arguments; const argsLen = args.length; diff --git a/scripts/eslint/rules/jsdoc-format.cjs b/scripts/eslint/rules/jsdoc-format.cjs index b16de44b4aaa5..4753fe9cc84cc 100644 --- a/scripts/eslint/rules/jsdoc-format.cjs +++ b/scripts/eslint/rules/jsdoc-format.cjs @@ -1,4 +1,3 @@ -const { TSESTree } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); module.exports = createRule({ @@ -29,7 +28,7 @@ module.exports = createRule({ return text.startsWith(jsdocStart); } - /** @type {(c: TSESTree.Comment, indexInComment: number) => TSESTree.SourceLocation} */ + /** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment, indexInComment: number) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */ const getAtInternalLoc = (c, indexInComment) => { const line = c.loc.start.line; return { @@ -44,7 +43,7 @@ module.exports = createRule({ }; }; - /** @type {(c: TSESTree.Comment) => TSESTree.SourceLocation} */ + /** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */ const getJSDocStartLoc = c => { return { start: c.loc.start, @@ -55,7 +54,7 @@ module.exports = createRule({ }; }; - /** @type {(node: TSESTree.Node) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => void} */ const checkDeclaration = node => { const blockComments = sourceCode.getCommentsBefore(node).filter(c => c.type === "Block"); if (blockComments.length === 0) { diff --git a/scripts/eslint/rules/no-in-operator.cjs b/scripts/eslint/rules/no-in-operator.cjs index cbd357b86823e..b81d346eaa828 100644 --- a/scripts/eslint/rules/no-in-operator.cjs +++ b/scripts/eslint/rules/no-in-operator.cjs @@ -1,4 +1,3 @@ -const { TSESTree } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); module.exports = createRule({ @@ -17,7 +16,7 @@ module.exports = createRule({ create(context) { const IN_OPERATOR = "in"; - /** @type {(node: TSESTree.BinaryExpression) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.BinaryExpression) => void} */ const checkInOperator = node => { if (node.operator === IN_OPERATOR) { context.report({ messageId: "noInOperatorError", node }); diff --git a/scripts/eslint/rules/no-keywords.cjs b/scripts/eslint/rules/no-keywords.cjs index a0032bf5ff102..7aee37ed35dc7 100644 --- a/scripts/eslint/rules/no-keywords.cjs +++ b/scripts/eslint/rules/no-keywords.cjs @@ -1,4 +1,4 @@ -const { TSESTree, AST_NODE_TYPES } = require("@typescript-eslint/utils"); +const { AST_NODE_TYPES } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); module.exports = createRule({ @@ -37,12 +37,12 @@ module.exports = createRule({ /** @type {(name: string) => boolean} */ const isKeyword = name => keywords.includes(name); - /** @type {(node: TSESTree.Identifier) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Identifier) => void} */ const report = node => { context.report({ messageId: "noKeywordsError", data: { name: node.name }, node }); }; - /** @type {(node: TSESTree.ObjectPattern) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.ObjectPattern) => void} */ const checkProperties = node => { node.properties.forEach(property => { if ( @@ -56,7 +56,7 @@ module.exports = createRule({ }); }; - /** @type {(node: TSESTree.ArrayPattern) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrayPattern) => void} */ const checkElements = node => { node.elements.forEach(element => { if ( @@ -69,7 +69,7 @@ module.exports = createRule({ }); }; - /** @type {(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSMethodSignature | TSESTree.TSFunctionType) => void} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrowFunctionExpression | import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression | import("@typescript-eslint/utils").TSESTree.TSMethodSignature | import("@typescript-eslint/utils").TSESTree.TSFunctionType) => void} */ const checkParams = node => { if (!node || !node.params || !node.params.length) { return; diff --git a/scripts/eslint/rules/only-arrow-functions.cjs b/scripts/eslint/rules/only-arrow-functions.cjs index 9abde8775c08d..d887a05467f51 100644 --- a/scripts/eslint/rules/only-arrow-functions.cjs +++ b/scripts/eslint/rules/only-arrow-functions.cjs @@ -1,6 +1,8 @@ -const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils"); +const { AST_NODE_TYPES } = require("@typescript-eslint/utils"); const { createRule } = require("./utils.cjs"); +/** @typedef {import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression} FunctionDeclarationOrExpression */ + module.exports = createRule({ name: "only-arrow-functions", meta: { @@ -27,10 +29,10 @@ module.exports = createRule({ }], create(context, [{ allowNamedFunctions, allowDeclarations }]) { - /** @type {(node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression) => boolean} */ + /** @type {(node: FunctionDeclarationOrExpression) => boolean} */ const isThisParameter = node => !!node.params.length && !!node.params.find(param => param.type === AST_NODE_TYPES.Identifier && param.name === "this"); - /** @type {(node: TSESTree.Node) => boolean} */ + /** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */ const isMethodType = node => { const types = [ AST_NODE_TYPES.MethodDefinition, @@ -57,7 +59,7 @@ module.exports = createRule({ } }; - /** @type {(node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression) => void} */ + /** @type {(node: FunctionDeclarationOrExpression) => void} */ const exitFunction = node => { const methodUsesThis = stack.pop(); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index 40ec90cd8d82b..42dd5ca6e60bb 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -13,11 +13,8 @@ "strict": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, - "allowUnusedLabels": false, "noImplicitOverride": true, "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, "allowJs": true, "checkJs": true }, diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 9738920df7527..1ee2fefe16048 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1,5 +1,4 @@ import { - __String, CharacterCodes, Comparer, Comparison, @@ -286,7 +285,7 @@ export function filter<T>(array: T[], f: (x: T) => boolean): T[]; /** @internal */ export function filter<T, U extends T>(array: readonly T[], f: (x: T) => x is U): readonly U[]; /** @internal */ -export function filter<T, U extends T>(array: readonly T[], f: (x: T) => boolean): readonly T[]; +export function filter<T>(array: readonly T[], f: (x: T) => boolean): readonly T[]; /** @internal */ export function filter<T, U extends T>(array: T[] | undefined, f: (x: T) => x is U): U[] | undefined; /** @internal */ @@ -294,7 +293,7 @@ export function filter<T>(array: T[] | undefined, f: (x: T) => boolean): T[] | u /** @internal */ export function filter<T, U extends T>(array: readonly T[] | undefined, f: (x: T) => x is U): readonly U[] | undefined; /** @internal */ -export function filter<T, U extends T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined; +export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined; /** @internal */ export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined { if (array) { @@ -830,7 +829,7 @@ export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Compa } /** @internal */ -export function sortAndDeduplicate<T>(array: readonly string[]): SortedReadonlyArray<string>; +export function sortAndDeduplicate(array: readonly string[]): SortedReadonlyArray<string>; /** @internal */ export function sortAndDeduplicate<T>(array: readonly T[], comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>; /** @internal */ diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7b7f0fcfa8143..6842fb1c8c71c 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4131,6 +4131,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri writeSpace(); nextPos = emitTokenWithComment(SyntaxKind.AsKeyword, nextPos, writeKeyword, node); writeSpace(); + // eslint-disable-next-line @typescript-eslint/no-unused-vars nextPos = emitTokenWithComment(SyntaxKind.NamespaceKeyword, nextPos, writeKeyword, node); writeSpace(); emit(node.name); diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index e952b614251c7..28c88fe2136f3 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -1675,7 +1675,7 @@ export function createAccessorPropertyGetRedirector(factory: NodeFactory, node: * * @internal */ -export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()) { +export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()): SetAccessorDeclaration { return factory.createSetAccessorDeclaration( modifiers, name, diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index db767177462e8..eeff8c96c7bbf 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -348,7 +348,7 @@ interface PackageJson extends PackageJsonPathFields { version?: string; } -function readPackageJsonField<TMatch, K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined; +function readPackageJsonField<K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined; function readPackageJsonField<K extends MatchingKeys<PackageJson, object | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined; function readPackageJsonField<K extends keyof PackageJson>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string" | "object", state: ModuleResolutionState): PackageJson[K] | undefined { if (!hasProperty(jsonContent, fieldName)) { diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 420b59071266b..0a95aeafdab37 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -258,18 +258,18 @@ export interface ProgramHost<T extends BuilderProgram> { getModuleResolutionCache?(): ModuleResolutionCache | undefined; jsDocParsingMode?: JSDocParsingMode; -} -/** - * Internal interface used to wire emit through same host - * - * @internal - */ -export interface ProgramHost<T extends BuilderProgram> { + + // Internal interface used to wire emit through same host + // TODO: GH#18217 Optional methods are frequently asserted + /** @internal */ createDirectory?(path: string): void; + /** @internal */ writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void; // For testing + /** @internal */ storeFilesChangingSignatureDuringEmit?: boolean; + /** @internal */ now?(): Date; } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index cf6c72efaca0a..624360c4fc7e0 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -504,7 +504,7 @@ export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) { /** @internal */ export function convertUserPreferences(preferences: protocol.UserPreferences): UserPreferences { - const { lazyConfiguredProjectsFromExternalProject, ...userPreferences } = preferences; + const { lazyConfiguredProjectsFromExternalProject: _, ...userPreferences } = preferences; return userPreferences; } diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts index df99139e709c7..267cabc534e02 100644 --- a/src/services/codefixes/fixAddMissingConstraint.ts +++ b/src/services/codefixes/fixAddMissingConstraint.ts @@ -132,7 +132,7 @@ function addMissingConstraint(changes: textChanges.ChangeTracker, program: Progr } function tryGetConstraintFromDiagnosticMessage(messageText: string | DiagnosticMessageChain) { - const [_, constraint] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/`extends (.*)`/) || []; + const [, constraint] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/`extends (.*)`/) || []; return constraint; } diff --git a/src/services/codefixes/fixNaNEquality.ts b/src/services/codefixes/fixNaNEquality.ts index 53db6b1b8b8d6..bd64d8b82a70a 100644 --- a/src/services/codefixes/fixNaNEquality.ts +++ b/src/services/codefixes/fixNaNEquality.ts @@ -87,6 +87,6 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ar } function getSuggestion(messageText: string | DiagnosticMessageChain) { - const [_, suggestion] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/'(.*)'/) || []; + const [, suggestion] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/'(.*)'/) || []; return suggestion; } diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 1c2a7a6e70265..80064ab148951 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -2,7 +2,6 @@ import { getModuleSpecifier, } from "../../compiler/moduleSpecifiers"; import { - __String, AnyImportOrRequireStatement, append, ApplicableRefactorInfo, diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 3b772f7d33f0f..498bd88917da4 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -21,10 +21,6 @@ "useUnknownInCatchVariables": false, "noImplicitOverride": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "allowUnusedLabels": false, - "skipLibCheck": true, "alwaysStrict": true,