diff --git a/.eslintrc.json b/.eslintrc.json index 1a81fa72497c6..0eb936e9be5c8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -104,8 +104,6 @@ ], // Todo: For each of these, investigate whether we want to enable them ✨ - "prefer-rest-params": "off", - "prefer-spread": "off", "@typescript-eslint/no-unused-vars": "off", // Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820 diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1865ecb9a7bb1..c43435bc001c5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19844,7 +19844,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const childrenPropName = childPropName === undefined ? "children" : unescapeLeadingUnderscores(childPropName); const childrenTargetType = getIndexedAccessType(target, getStringLiteralType(childrenPropName)); const diagnostic = Diagnostics._0_components_don_t_accept_text_as_child_elements_Text_in_JSX_has_the_type_string_but_the_expected_type_of_1_is_2; - invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: formatMessage(/*dummy*/ undefined, diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) }; + invalidTextDiagnostic = { ...diagnostic, key: "!!ALREADY FORMATTED!!", message: formatMessage(diagnostic, tagNameText, childrenPropName, typeToString(childrenTargetType)) }; } return invalidTextDiagnostic; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 5fcd8525a9720..4004f0260ee8f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -6,6 +6,7 @@ import { arrayToMap, assign, BuildOptions, + cast, changeExtension, CharacterCodes, combinePaths, @@ -2018,9 +2019,8 @@ export function parseBuildCommand(args: readonly string[]): ParsedBuildCommand { } /** @internal */ -export function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string { - const diagnostic = createCompilerDiagnostic.apply(undefined, arguments); - return diagnostic.messageText as string; +export function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string { + return cast(createCompilerDiagnostic(message, ...args).messageText, isString); } export type DiagnosticReporter = (diagnostic: Diagnostic) => void; diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6f80f5f145d30..f5d60b0459141 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2061,6 +2061,7 @@ export function compose(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t if (!!e) { const args: ((t: T) => T)[] = []; for (let i = 0; i < arguments.length; i++) { + // eslint-disable-next-line prefer-rest-params args[i] = arguments[i]; } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 4538377dafd3d..3049f8b742d9d 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -115,9 +115,8 @@ import { } from "./_namespaces/ts"; /** @internal */ -export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; -export function trace(host: ModuleResolutionHost): void { - host.trace!(formatMessage.apply(undefined, arguments)); +export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void { + host.trace!(formatMessage(message, ...args)); } /** @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 436fb32872c6e..638d76f79b53e 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -8121,8 +8121,8 @@ export function setObjectAllocator(alloc: ObjectAllocator) { } /** @internal */ -export function formatStringFromArgs(text: string, args: ArrayLike, baseIndex = 0): string { - return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.checkDefined(args[+index + baseIndex])); +export function formatStringFromArgs(text: string, args: DiagnosticArguments): string { + return text.replace(/{(\d+)}/g, (_match, index: string) => "" + Debug.checkDefined(args[+index])); } let localizedDiagnosticMessages: MapLike | undefined; @@ -8147,14 +8147,12 @@ export function getLocaleSpecificMessage(message: DiagnosticMessage) { } /** @internal */ -export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation; -/** @internal */ -export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage): DiagnosticWithDetachedLocation { +export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation { assertDiagnosticLocation(/*file*/ undefined, start, length); let text = getLocaleSpecificMessage(message); - if (arguments.length > 4) { - text = formatStringFromArgs(text, arguments, 4); + if (some(args)) { + text = formatStringFromArgs(text, args); } return { @@ -8218,15 +8216,13 @@ export function attachFileToDiagnostics(diagnostics: DiagnosticWithDetachedLocat } /** @internal */ -export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation; -/** @internal */ -export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation { +export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { assertDiagnosticLocation(file, start, length); let text = getLocaleSpecificMessage(message); - if (arguments.length > 4) { - text = formatStringFromArgs(text, arguments, 4); + if (some(args)) { + text = formatStringFromArgs(text, args); } return { @@ -8243,26 +8239,22 @@ export function createFileDiagnostic(file: SourceFile, start: number, length: nu } /** @internal */ -export function formatMessage(_dummy: any, message: DiagnosticMessage, ...args: DiagnosticArguments): string; -/** @internal */ -export function formatMessage(_dummy: any, message: DiagnosticMessage): string { +export function formatMessage(message: DiagnosticMessage, ...args: DiagnosticArguments): string { let text = getLocaleSpecificMessage(message); - if (arguments.length > 2) { - text = formatStringFromArgs(text, arguments, 2); + if (some(args)) { + text = formatStringFromArgs(text, args); } return text; } /** @internal */ -export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic; -/** @internal */ -export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic { +export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic { let text = getLocaleSpecificMessage(message); - if (arguments.length > 1) { - text = formatStringFromArgs(text, arguments, 1); + if (some(args)) { + text = formatStringFromArgs(text, args); } return { @@ -8293,13 +8285,11 @@ export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessag } /** @internal */ -export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticMessageChain; -/** @internal */ -export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage): DiagnosticMessageChain { +export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticMessageChain { let text = getLocaleSpecificMessage(message); - if (arguments.length > 2) { - text = formatStringFromArgs(text, arguments, 2); + if (some(args)) { + text = formatStringFromArgs(text, args); } return { messageText: text, diff --git a/src/deprecatedCompat/deprecate.ts b/src/deprecatedCompat/deprecate.ts index 661da6980d437..cc6b2f31c31ed 100644 --- a/src/deprecatedCompat/deprecate.ts +++ b/src/deprecatedCompat/deprecate.ts @@ -24,7 +24,7 @@ function formatDeprecationMessage(name: string, error: boolean | undefined, erro deprecationMessage += `'${name}' `; deprecationMessage += since ? `has been deprecated since v${since}` : "is deprecated"; deprecationMessage += error ? " and can no longer be used." : errorAfter ? ` and will no longer be usable after v${errorAfter}.` : "."; - deprecationMessage += message ? ` ${formatStringFromArgs(message, [name], 0)}` : ""; + deprecationMessage += message ? ` ${formatStringFromArgs(message, [name])}` : ""; return deprecationMessage; } @@ -62,6 +62,7 @@ export function createDeprecation(name: string, options: DeprecationOptions = {} function wrapFunction any>(deprecation: () => void, func: F): F { return function (this: unknown) { deprecation(); + // eslint-disable-next-line prefer-rest-params return func.apply(this, arguments); } as F; } diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index b6f1d1ddedd7c..660effc571d48 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -486,7 +486,7 @@ function printEasyHelp(sys: System, simpleOptions: readonly CommandLineOption[]) output = [ ...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.COMMAND_LINE_FLAGS), cliCommands, /*subCategory*/ false, /*beforeOptionsDescription*/ undefined, /*afterOptionsDescription*/ undefined), - ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.COMMON_COMPILER_OPTIONS), configOpts, /*subCategory*/ false, /*beforeOptionsDescription*/ undefined, formatMessage(/*dummy*/ undefined, Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc")) + ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.COMMON_COMPILER_OPTIONS), configOpts, /*subCategory*/ false, /*beforeOptionsDescription*/ undefined, formatMessage(Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc")) ]; for (const line of output) { @@ -504,9 +504,9 @@ function printEasyHelp(sys: System, simpleOptions: readonly CommandLineOption[]) function printAllHelp(sys: System, compilerOptions: readonly CommandLineOption[], buildOptions: readonly CommandLineOption[], watchOptions: readonly CommandLineOption[]) { let output: string[] = [...getHeader(sys,`${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)]; - output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.ALL_COMPILER_OPTIONS), compilerOptions, /*subCategory*/ true, /*beforeOptionsDescription*/ undefined, formatMessage(/*dummy*/ undefined, Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc"))]; + output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.ALL_COMPILER_OPTIONS), compilerOptions, /*subCategory*/ true, /*beforeOptionsDescription*/ undefined, formatMessage(Diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0, "https://aka.ms/tsc"))]; output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.WATCH_OPTIONS), watchOptions, /*subCategory*/ false, getDiagnosticText(Diagnostics.Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_config_watch_mode_with_Colon))]; - output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(/*dummy*/ undefined, Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; + output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; for (const line of output) { sys.write(line); } @@ -514,7 +514,7 @@ function printAllHelp(sys: System, compilerOptions: readonly CommandLineOption[] function printBuildHelp(sys: System, buildOptions: readonly CommandLineOption[]) { let output: string[] = [...getHeader(sys,`${getDiagnosticText(Diagnostics.tsc_Colon_The_TypeScript_Compiler)} - ${getDiagnosticText(Diagnostics.Version_0, version)}`)]; - output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(/*dummy*/ undefined, Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; + output = [...output, ...generateSectionOptionsOutput(sys, getDiagnosticText(Diagnostics.BUILD_OPTIONS), buildOptions, /*subCategory*/ false, formatMessage(Diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0, "https://aka.ms/tsc-composite-builds"))]; for (const line of output) { sys.write(line); } diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index c34050f8f8bc1..634a80bdf0871 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3279,7 +3279,7 @@ export class TestState { assert.equal(action.description, options.description); } else if (Array.isArray(options.description)) { - const description = ts.formatStringFromArgs(options.description[0], options.description, 1); + const description = ts.formatStringFromArgs(options.description[0], options.description.slice(1)); assert.equal(action.description, description); } else { @@ -4333,7 +4333,7 @@ export class TestState { public toggleLineComment(newFileContent: string): void { const changes: ts.TextChange[] = []; for (const range of this.getRanges()) { - changes.push.apply(changes, this.languageService.toggleLineComment(this.activeFile.fileName, range)); + changes.push(...this.languageService.toggleLineComment(this.activeFile.fileName, range)); } this.applyEdits(this.activeFile.fileName, changes); @@ -4344,7 +4344,7 @@ export class TestState { public toggleMultilineComment(newFileContent: string): void { const changes: ts.TextChange[] = []; for (const range of this.getRanges()) { - changes.push.apply(changes, this.languageService.toggleMultilineComment(this.activeFile.fileName, range)); + changes.push(...this.languageService.toggleMultilineComment(this.activeFile.fileName, range)); } this.applyEdits(this.activeFile.fileName, changes); @@ -4355,7 +4355,7 @@ export class TestState { public commentSelection(newFileContent: string): void { const changes: ts.TextChange[] = []; for (const range of this.getRanges()) { - changes.push.apply(changes, this.languageService.commentSelection(this.activeFile.fileName, range)); + changes.push(...this.languageService.commentSelection(this.activeFile.fileName, range)); } this.applyEdits(this.activeFile.fileName, changes); @@ -4366,7 +4366,7 @@ export class TestState { public uncommentSelection(newFileContent: string): void { const changes: ts.TextChange[] = []; for (const range of this.getRanges()) { - changes.push.apply(changes, this.languageService.uncommentSelection(this.activeFile.fileName, range)); + changes.push(...this.languageService.uncommentSelection(this.activeFile.fileName, range)); } this.applyEdits(this.activeFile.fileName, changes); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 26682df5cdf1e..e059aad96f1f5 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -17,6 +17,7 @@ export function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageS for (const k of Object.keys(langSvc)) { // eslint-disable-next-line local/only-arrow-functions proxy[k] = function () { + // eslint-disable-next-line prefer-spread, prefer-rest-params return langSvc[k].apply(langSvc, arguments); }; } @@ -901,6 +902,7 @@ class SessionServerHost implements ts.server.ServerHost, ts.server.Logger { const langSvc: any = info.languageService; // eslint-disable-next-line local/only-arrow-functions proxy.getQuickInfoAtPosition = function () { + // eslint-disable-next-line prefer-spread, prefer-rest-params const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments); if (parts.displayParts.length > 0) { parts.displayParts[0].text = "Proxied"; diff --git a/src/services/services.ts b/src/services/services.ts index 51dcb93f7dd58..b0e56cc06453f 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2614,7 +2614,7 @@ export function createLanguageService( // If the line is not an empty line; otherwise no-op. if (lineTextStart !== undefined) { if (isJsx) { - textChanges.push.apply(textChanges, toggleMultilineComment(fileName, { pos: lineStarts[i] + leftMostPosition, end: sourceFile.getLineEndOfPosition(lineStarts[i]) }, isCommenting, isJsx)); + textChanges.push(...toggleMultilineComment(fileName, { pos: lineStarts[i] + leftMostPosition, end: sourceFile.getLineEndOfPosition(lineStarts[i]) }, isCommenting, isJsx)); } else if (isCommenting) { textChanges.push({ @@ -2788,10 +2788,10 @@ export function createLanguageService( if (commentRange) { switch (commentRange.kind) { case SyntaxKind.SingleLineCommentTrivia: - textChanges.push.apply(textChanges, toggleLineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); + textChanges.push(...toggleLineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); break; case SyntaxKind.MultiLineCommentTrivia: - textChanges.push.apply(textChanges, toggleMultilineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); + textChanges.push(...toggleMultilineComment(fileName, { end: commentRange.end, pos: commentRange.pos + 1 }, /*insertComment*/ false)); } i = commentRange.end + 1;