From e66d83739010c10eadd970e9e0ae3fc7af909fb9 Mon Sep 17 00:00:00 2001
From: Benjamin Franzke <ben@bnf.dev>
Date: Sat, 26 Aug 2023 20:51:30 +0200
Subject: [PATCH] [TASK] Define readonly for never-written private TypeScript
 variables

IDEs like PhpSstorm complain about the same thing,
so better we have that defined and checked via CI.

Commands executed:
  node_modules/.bin/eslint --fix Sources/TypeScript/

Resolves: #101780
Releases: main, 12.4
Change-Id: I01e0289b671dfd4348319bca90dddaec085fbfe4
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80747
Reviewed-by: Benjamin Franzke <ben@bnf.dev>
Tested-by: Benjamin Franzke <ben@bnf.dev>
Tested-by: core-ci <typo3@b13.com>
---
 Build/.eslintrc.json                          |  1 +
 .../TypeScript/adminpanel/modules/cache.ts    |  2 +-
 .../TypeScript/adminpanel/modules/preview.ts  |  4 +-
 .../TypeScript/backend/context-help.ts        |  6 +--
 .../TypeScript/backend/context-menu.ts        |  4 +-
 .../TypeScript/backend/date-time-picker.ts    |  2 +-
 .../TypeScript/backend/document-header.ts     |  4 +-
 .../backend/document-save-actions.ts          |  2 +-
 .../TypeScript/backend/drag-uploader.ts       | 18 +++----
 .../TypeScript/backend/element-browser.ts     |  4 +-
 .../TypeScript/backend/form-engine-suggest.ts |  2 +-
 .../container/files-control-container.ts      |  2 +-
 .../container/flex-form-section-container.ts  |  2 +-
 .../container/inline-control-container.ts     |  4 +-
 .../container/site-language-container.ts      |  2 +-
 .../element/abstract-sortable-select-items.ts |  2 +-
 .../form-engine/element/category-element.ts   |  6 +--
 .../element/extra/select-box-filter.ts        |  2 +-
 .../form-engine/element/mfa-info-element.ts   |  2 +-
 .../element/select-check-box-element.ts       |  2 +-
 .../element/select-tree-element.ts            |  6 +--
 .../element/select-tree-toolbar.ts            |  2 +-
 .../form-engine/element/slug-element.ts       |  2 +-
 .../form-engine/field-control/add-record.ts   |  2 +-
 .../form-engine/field-control/edit-popup.ts   |  4 +-
 .../field-control/insert-clipboard.ts         |  2 +-
 .../form-engine/field-control/link-popup.ts   |  2 +-
 .../form-engine/field-control/list-module.ts  |  2 +-
 .../field-control/password-generator.ts       |  2 +-
 .../field-control/reset-selection.ts          |  2 +-
 .../form-engine/field-wizard/value-picker.ts  |  2 +-
 .../form-engine/field-wizard/value-slider.ts  |  2 +-
 .../backend/form-engine/request-update.ts     |  2 +-
 .../backend/global-event-handler.ts           |  2 +-
 .../TypeScript/backend/image-manipulation.ts  | 14 +++---
 .../TypeScript/backend/layout-module/paste.ts |  2 +-
 .../TypeScript/backend/link-browser.ts        |  2 +-
 .../TypeScript/backend/localization.ts        |  2 +-
 .../TypeScript/backend/login-refresh.ts       |  2 +-
 Build/Sources/TypeScript/backend/modal.ts     |  4 +-
 .../TypeScript/backend/notification.ts        |  2 +-
 .../TypeScript/backend/page-link-handler.ts   |  2 +-
 .../backend/page-tree/page-tree-element.ts    | 22 ++++----
 .../TypeScript/backend/record-search.ts       |  4 +-
 .../Sources/TypeScript/backend/recordlist.ts  |  6 +--
 .../backend/storage/module-state-storage.ts   |  2 +-
 .../backend/toolbar/clear-cache-menu.ts       |  2 +-
 .../TypeScript/backend/toolbar/live-search.ts |  2 +-
 .../backend/toolbar/shortcut-menu.ts          |  2 +-
 .../toolbar/system-information-menu.ts        |  2 +-
 .../TypeScript/backend/tree/drag-drop.ts      |  4 +-
 .../backend/tree/file-storage-browser.ts      |  6 +--
 .../tree/file-storage-tree-container.ts       | 22 ++++----
 .../TypeScript/backend/tree/page-browser.ts   |  8 +--
 .../TypeScript/backend/user-pass-login.ts     |  2 +-
 .../utility/collapse-state-persister.ts       |  2 +-
 .../backend/viewport/resizable-navigation.ts  | 14 +++---
 .../Sources/TypeScript/beuser/permissions.ts  |  4 +-
 .../TypeScript/core/ajax/ajax-request.ts      |  2 +-
 .../core/java-script-item-processor.ts        |  2 +-
 .../TypeScript/extensionmanager/repository.ts |  2 +-
 .../TypeScript/filelist/browse-files.ts       |  2 +-
 .../TypeScript/filelist/browse-folders.ts     |  2 +-
 .../TypeScript/filelist/file-list-dragdrop.ts |  6 +--
 .../Sources/TypeScript/filelist/file-list.ts  |  2 +-
 .../form/backend/form-editor/core.ts          |  4 +-
 .../TypeScript/form/backend/form-manager.ts   |  2 +-
 .../TypeScript/install/ajax/ajax-queue.ts     |  2 +-
 Build/Sources/TypeScript/install/installer.ts | 16 +++---
 .../module/environment/environment-check.ts   |  6 +--
 .../module/environment/folder-structure.ts    | 16 +++---
 .../module/environment/image-processing.ts    | 12 ++---
 .../install/module/environment/mail-test.ts   |  4 +-
 .../module/maintenance/clear-tables.ts        | 16 +++---
 .../maintenance/clear-typo3temp-files.ts      | 14 +++---
 .../module/maintenance/create-admin.ts        |  2 +-
 .../module/maintenance/database-analyzer.ts   | 12 ++---
 .../module/maintenance/language-packs.ts      | 22 ++++----
 .../settings/change-install-tool-password.ts  |  2 +-
 .../settings/extension-configuration.ts       |  4 +-
 .../install/module/settings/features.ts       |  2 +-
 .../module/settings/local-configuration.ts    |  8 +--
 .../install/module/settings/presets.ts        |  6 +--
 .../module/settings/system-maintainer.ts      |  6 +--
 .../install/module/upgrade/core-update.ts     |  6 +--
 .../module/upgrade/extension-compat-tester.ts |  6 +--
 .../module/upgrade/extension-scanner.ts       | 10 ++--
 .../module/upgrade/tca-ext-tables-check.ts    |  4 +-
 .../module/upgrade/tca-migrations-check.ts    |  4 +-
 .../install/module/upgrade/upgrade-docs.ts    | 10 ++--
 .../install/module/upgrade/upgrade-wizards.ts | 50 +++++++++----------
 .../install/renderable/flash-message.ts       |  2 +-
 .../TypeScript/install/renderable/info-box.ts |  2 +-
 .../install/renderable/progress-bar.ts        |  2 +-
 Build/Sources/TypeScript/install/router.ts    | 10 ++--
 .../TypeScript/lowlevel/query-generator.ts    |  4 +-
 .../opendocs/toolbar/opendocs-menu.ts         |  2 +-
 Build/Sources/TypeScript/recycler/recycler.ts |  6 +--
 .../Sources/TypeScript/workspaces/backend.ts  | 24 ++++-----
 .../Sources/TypeScript/workspaces/preview.ts  | 10 ++--
 100 files changed, 284 insertions(+), 283 deletions(-)

diff --git a/Build/.eslintrc.json b/Build/.eslintrc.json
index 9960ae2dd02e..b8bbb2649c8e 100644
--- a/Build/.eslintrc.json
+++ b/Build/.eslintrc.json
@@ -34,6 +34,7 @@
     "@typescript-eslint/no-this-alias": "error",
     "@typescript-eslint/no-unused-vars": "error",
     "@typescript-eslint/member-ordering": "error",
+    "@typescript-eslint/prefer-readonly": "error",
     "@typescript-eslint/naming-convention": [
       "error",
       {
diff --git a/Build/Sources/TypeScript/adminpanel/modules/cache.ts b/Build/Sources/TypeScript/adminpanel/modules/cache.ts
index ce05a773d7e0..ad7eda807f86 100644
--- a/Build/Sources/TypeScript/adminpanel/modules/cache.ts
+++ b/Build/Sources/TypeScript/adminpanel/modules/cache.ts
@@ -1,7 +1,7 @@
 // eslint-disable-next-line @typescript-eslint/no-namespace
 namespace TYPO3 {
   export class Cache {
-    private buttons: NodeList;
+    private readonly buttons: NodeList;
 
     constructor() {
       this.buttons = document.querySelectorAll('[data-typo3-role="clearCacheButton"]');
diff --git a/Build/Sources/TypeScript/adminpanel/modules/preview.ts b/Build/Sources/TypeScript/adminpanel/modules/preview.ts
index 5be3d68d8654..1e47aba7a30a 100644
--- a/Build/Sources/TypeScript/adminpanel/modules/preview.ts
+++ b/Build/Sources/TypeScript/adminpanel/modules/preview.ts
@@ -30,7 +30,7 @@ namespace TYPO3 {
       this.timeField.addEventListener('change', this.updateDateField);
     }
 
-    private toggleDisplay = (): void => {
+    private readonly toggleDisplay = (): void => {
       const toggleVal = this.toggleField.checked;
       const groupElement = <HTMLDivElement>document.getElementById('typo3-adminPanel-preview_simulateDate');
       if (toggleVal) {
@@ -46,7 +46,7 @@ namespace TYPO3 {
       }
     };
 
-    private updateDateField = (): void => {
+    private readonly updateDateField = (): void => {
       let dateVal = this.dateField.value;
       let timeVal = this.timeField.value;
       if (!dateVal && timeVal) {
diff --git a/Build/Sources/TypeScript/backend/context-help.ts b/Build/Sources/TypeScript/backend/context-help.ts
index a952529adb70..d3f8b51cd7d7 100644
--- a/Build/Sources/TypeScript/backend/context-help.ts
+++ b/Build/Sources/TypeScript/backend/context-help.ts
@@ -22,9 +22,9 @@ import RegularEvent from '@typo3/core/event/regular-event';
  * @exports @typo3/backend/context-help
  */
 class ContextHelp {
-  private trigger: string = 'click';
-  private placement: string = 'auto';
-  private selector: string = '.help-link';
+  private readonly trigger: string = 'click';
+  private readonly placement: string = 'auto';
+  private readonly selector: string = '.help-link';
 
   constructor() {
     this.initialize();
diff --git a/Build/Sources/TypeScript/backend/context-menu.ts b/Build/Sources/TypeScript/backend/context-menu.ts
index c9d5abb0f985..535adb6589e0 100644
--- a/Build/Sources/TypeScript/backend/context-menu.ts
+++ b/Build/Sources/TypeScript/backend/context-menu.ts
@@ -49,7 +49,7 @@ interface MenuItems {
 class ContextMenu {
   private mousePos: MousePosition = { X: null, Y: null };
   private record: ActiveRecord = { uid: null, table: null };
-  private eventSources: Element[] = [];
+  private readonly eventSources: Element[] = [];
 
   constructor() {
     document.addEventListener('click', (event: PointerEvent) => {
@@ -503,7 +503,7 @@ class ContextMenu {
    * actual position of the mouse
    * in the context menu object
    */
-  private storeMousePositionEvent = (event: MouseEvent): void => {
+  private readonly storeMousePositionEvent = (event: MouseEvent): void => {
     this.mousePos = { X: event.pageX, Y: event.pageY };
   };
 
diff --git a/Build/Sources/TypeScript/backend/date-time-picker.ts b/Build/Sources/TypeScript/backend/date-time-picker.ts
index 0714917a38e5..14ca9db14471 100644
--- a/Build/Sources/TypeScript/backend/date-time-picker.ts
+++ b/Build/Sources/TypeScript/backend/date-time-picker.ts
@@ -26,7 +26,7 @@ interface FlatpickrInputElement extends HTMLInputElement {
  * and EXT:belog and EXT:scheduler
  */
 class DateTimePicker {
-  private format: string = (typeof opener?.top?.TYPO3 !== 'undefined' ? opener.top : top).TYPO3.settings.DateTimePicker.DateFormat;
+  private readonly format: string = (typeof opener?.top?.TYPO3 !== 'undefined' ? opener.top : top).TYPO3.settings.DateTimePicker.DateFormat;
 
   /**
    * Format a given date for the hidden FormEngine field
diff --git a/Build/Sources/TypeScript/backend/document-header.ts b/Build/Sources/TypeScript/backend/document-header.ts
index 1ba5b7d5f531..d9c84356c1d6 100644
--- a/Build/Sources/TypeScript/backend/document-header.ts
+++ b/Build/Sources/TypeScript/backend/document-header.ts
@@ -22,7 +22,7 @@ class DocumentHeader {
   private documentHeader: HTMLElement = null;
 
   private direction: string = 'down';
-  private reactionRange: number = 300;
+  private readonly reactionRange: number = 300;
   private lastPosition: number = 0;
   private currentPosition: number = 0;
   private changedPosition: number = 0;
@@ -52,7 +52,7 @@ class DocumentHeader {
    *
    * @param {Event} e
    */
-  private scroll = (e: Event): void => {
+  private readonly scroll = (e: Event): void => {
     this.currentPosition = (e.target as HTMLElement).scrollTop;
     if (this.currentPosition > this.lastPosition) {
       if (this.direction !== 'down') {
diff --git a/Build/Sources/TypeScript/backend/document-save-actions.ts b/Build/Sources/TypeScript/backend/document-save-actions.ts
index a25b895d1a65..72c0d326484e 100644
--- a/Build/Sources/TypeScript/backend/document-save-actions.ts
+++ b/Build/Sources/TypeScript/backend/document-save-actions.ts
@@ -19,7 +19,7 @@ type PreSubmitCallback = (e: JQueryEventObject) => void;
 
 class DocumentSaveActions {
   private static instance: DocumentSaveActions = null;
-  private preSubmitCallbacks: PreSubmitCallback[] = [];
+  private readonly preSubmitCallbacks: PreSubmitCallback[] = [];
 
   private constructor() {
     DocumentService.ready().then((): void => {
diff --git a/Build/Sources/TypeScript/backend/drag-uploader.ts b/Build/Sources/TypeScript/backend/drag-uploader.ts
index 9ed45a8e7ab7..d33e10817407 100644
--- a/Build/Sources/TypeScript/backend/drag-uploader.ts
+++ b/Build/Sources/TypeScript/backend/drag-uploader.ts
@@ -99,12 +99,12 @@ class DragUploaderPlugin {
 
   private percentagePerFile: number = 1;
 
-  private $body: JQuery;
+  private readonly $body: JQuery;
   private readonly $element: JQuery;
   private readonly $dropzone: JQuery;
   private readonly $dropzoneMask: JQuery;
   private readonly fileInput: HTMLInputElement;
-  private browserCapabilities: { fileReader: boolean; DnD: boolean; Progress: boolean };
+  private readonly browserCapabilities: { fileReader: boolean; DnD: boolean; Progress: boolean };
   private readonly dropZoneInsertBefore: boolean;
   private queueLength: number;
   private readonly defaultAction: Action;
@@ -555,12 +555,12 @@ class FileQueueItem {
   private readonly file: File;
   private readonly override: Action;
   private readonly $selector: JQuery;
-  private $iconCol: JQuery;
-  private $fileName: JQuery;
-  private $progressBar: JQuery;
-  private $progressPercentage: JQuery;
-  private $progressMessage: JQuery;
-  private dragUploader: DragUploaderPlugin;
+  private readonly $iconCol: JQuery;
+  private readonly $fileName: JQuery;
+  private readonly $progressBar: JQuery;
+  private readonly $progressPercentage: JQuery;
+  private readonly $progressMessage: JQuery;
+  private readonly dragUploader: DragUploaderPlugin;
 
   constructor(dragUploader: DragUploaderPlugin, file: File, override: Action) {
     this.dragUploader = dragUploader;
@@ -831,7 +831,7 @@ class FileQueueItem {
 }
 
 class DragUploader {
-  private static options: DragUploaderOptions;
+  private static readonly options: DragUploaderOptions;
   public fileListColumnCount: number;
   public filesExtensionsAllowed: string;
   public fileDenyPattern: string;
diff --git a/Build/Sources/TypeScript/backend/element-browser.ts b/Build/Sources/TypeScript/backend/element-browser.ts
index 302e5c107e4b..8f4acdf66acd 100644
--- a/Build/Sources/TypeScript/backend/element-browser.ts
+++ b/Build/Sources/TypeScript/backend/element-browser.ts
@@ -45,11 +45,11 @@ class ElementBrowser {
   private fieldReference: string = '';
   private targetDoc: Window;
   private elRef: Element;
-  private rte: RTESettings = {
+  private readonly rte: RTESettings = {
     parameters: '',
     configuration: '',
   };
-  private irre: InlineSettings = {
+  private readonly irre: InlineSettings = {
     objectId: '',
   };
 
diff --git a/Build/Sources/TypeScript/backend/form-engine-suggest.ts b/Build/Sources/TypeScript/backend/form-engine-suggest.ts
index 87e332b163d6..8f9d5e34828a 100644
--- a/Build/Sources/TypeScript/backend/form-engine-suggest.ts
+++ b/Build/Sources/TypeScript/backend/form-engine-suggest.ts
@@ -103,7 +103,7 @@ class FormEngineSuggest {
     new RegularEvent('keydown', this.handleKeyDown).bindTo(this.element);
   }
 
-  private handleKeyDown = (e: KeyboardEvent): void => {
+  private readonly handleKeyDown = (e: KeyboardEvent): void => {
     if (e.key === 'ArrowDown') {
       e.preventDefault();
 
diff --git a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
index 263202c4f7d8..728ff5921954 100644
--- a/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/container/files-control-container.ts
@@ -184,7 +184,7 @@ class FilesControlContainer extends HTMLElement {
     }).delegateTo(this.container, Selectors.controlSectionSelector + ' [data-action="sort"]');
   }
 
-  private handlePostMessage = (e: MessageEvent): void => {
+  private readonly handlePostMessage = (e: MessageEvent): void => {
     if (!MessageUtility.verifyOrigin(e.origin)) {
       throw 'Denied message sent by ' + e.origin;
     }
diff --git a/Build/Sources/TypeScript/backend/form-engine/container/flex-form-section-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/flex-form-section-container.ts
index 9b9403db7f6c..8eeb030cccf0 100644
--- a/Build/Sources/TypeScript/backend/form-engine/container/flex-form-section-container.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/container/flex-form-section-container.ts
@@ -97,7 +97,7 @@ class FlexFormSectionContainer {
     });
   }
 
-  private updateSorting = (e: Sortable.SortableEvent): void => {
+  private readonly updateSorting = (e: Sortable.SortableEvent): void => {
     const actionFields: NodeListOf<HTMLInputElement> = this.container.querySelectorAll(Selectors.actionFieldSelector);
     actionFields.forEach((element: HTMLInputElement, key: number): void => {
       element.value = key.toString();
diff --git a/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
index d0052c32d07c..fd94fdddf348 100644
--- a/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/container/inline-control-container.ts
@@ -98,7 +98,7 @@ class InlineControlContainer {
   private appearance: Appearance = null;
   private requestQueue: RequestQueue = {};
   private progressQueue: ProgressQueue = {};
-  private noTitleString: string = (TYPO3.lang ? TYPO3.lang['FormEngine.noRecordTitle'] : '[No title]');
+  private readonly noTitleString: string = (TYPO3.lang ? TYPO3.lang['FormEngine.noRecordTitle'] : '[No title]');
 
   /**
    * @param {string} elementId
@@ -331,7 +331,7 @@ class InlineControlContainer {
   /**
    * @param {MessageEvent} e
    */
-  private handlePostMessage = (e: MessageEvent): void => {
+  private readonly handlePostMessage = (e: MessageEvent): void => {
     if (!MessageUtility.verifyOrigin(e.origin)) {
       throw 'Denied message sent by ' + e.origin;
     }
diff --git a/Build/Sources/TypeScript/backend/form-engine/container/site-language-container.ts b/Build/Sources/TypeScript/backend/form-engine/container/site-language-container.ts
index 7c4a00b1e079..2e019a84a55e 100644
--- a/Build/Sources/TypeScript/backend/form-engine/container/site-language-container.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/container/site-language-container.ts
@@ -264,7 +264,7 @@ class SiteLanguageContainer extends HTMLElement {
     }).delegateTo(this.container, Selectors.deleteRecordButtonSelector);
   }
 
-  private handlePostMessage = (e: MessageEvent): void => {
+  private readonly handlePostMessage = (e: MessageEvent): void => {
     if (!MessageUtility.verifyOrigin(e.origin)) {
       throw 'Denied message sent by ' + e.origin;
     }
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/abstract-sortable-select-items.ts b/Build/Sources/TypeScript/backend/form-engine/element/abstract-sortable-select-items.ts
index 18df45ccc452..6b18232ab0fc 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/abstract-sortable-select-items.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/abstract-sortable-select-items.ts
@@ -151,7 +151,7 @@ export abstract class AbstractSortableSelectItems {
   /**
    * @param {HTMLSelectElement} fieldElement
    */
-  private registerKeyboardEventHandler = (fieldElement: HTMLSelectElement): void => {
+  private readonly registerKeyboardEventHandler = (fieldElement: HTMLSelectElement): void => {
     const relatedFieldName = fieldElement.dataset.formengineInputName;
     const relatedField = FormEngine.getFieldElement(relatedFieldName).get(0) as HTMLSelectElement;
     const relatedAvailableValuesField = FormEngine.getFieldElement(relatedFieldName,'_avail').get(0) as HTMLSelectElement;
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/category-element.ts b/Build/Sources/TypeScript/backend/form-engine/element/category-element.ts
index 94a4c240e597..91754356619d 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/category-element.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/category-element.ts
@@ -108,7 +108,7 @@ class CategoryElement extends HTMLElement{
     });
   }
 
-  private selectNode = (evt: CustomEvent) => {
+  private readonly selectNode = (evt: CustomEvent) => {
     const node = evt.detail.node as TreeNode;
     this.updateAncestorsIndeterminateState(node);
     // check all nodes again, to ensure correct display of indeterminate state
@@ -122,7 +122,7 @@ class CategoryElement extends HTMLElement{
    * It's done once after loading data.
    * Later indeterminate state is updated just for the subset of nodes
    */
-  private loadDataAfter = (evt: CustomEvent) => {
+  private readonly loadDataAfter = (evt: CustomEvent) => {
     this.tree.nodes = evt.detail.nodes.map((node: TreeNode) => {
       node.indeterminate = false;
       return node;
@@ -133,7 +133,7 @@ class CategoryElement extends HTMLElement{
   /**
    * Sets a comma-separated list of selected nodes identifiers to configured input
    */
-  private saveCheckboxes = (): void => {
+  private readonly saveCheckboxes = (): void => {
     this.recordField.value = this.tree.getSelectedNodes().map((node: TreeNode): string => node.identifier).join(',');
   };
 
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/extra/select-box-filter.ts b/Build/Sources/TypeScript/backend/form-engine/element/extra/select-box-filter.ts
index b55c9a56562b..859936fa4409 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/extra/select-box-filter.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/extra/select-box-filter.ts
@@ -23,7 +23,7 @@ enum Selectors {
  * Select field filter functions, see TCA option "multiSelectFilterItems"
  */
 class SelectBoxFilter {
-  private selectElement: HTMLSelectElement = null;
+  private readonly selectElement: HTMLSelectElement = null;
   private filterText: string = '';
   private availableOptions: NodeListOf<HTMLOptionElement> = null;
 
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/mfa-info-element.ts b/Build/Sources/TypeScript/backend/form-engine/element/mfa-info-element.ts
index 8f86bd1da3cf..93201dc74e56 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/mfa-info-element.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/mfa-info-element.ts
@@ -43,7 +43,7 @@ enum Selectors {
 }
 
 class MfaInfoElement {
-  private options: FieldOptions = null;
+  private readonly options: FieldOptions = null;
   private fullElement: HTMLElement = null;
   private deactivteProviderButtons: NodeListOf<HTMLButtonElement> = null;
   private deactivteMfaButton: HTMLButtonElement = null;
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/select-check-box-element.ts b/Build/Sources/TypeScript/backend/form-engine/element/select-check-box-element.ts
index 01018991a508..c612d7734109 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/select-check-box-element.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/select-check-box-element.ts
@@ -21,7 +21,7 @@ enum Identifier {
 }
 
 class SelectCheckBoxElement {
-  private checkBoxId: string = '';
+  private readonly checkBoxId: string = '';
   private table: HTMLTableElement = null;
   private checkedBoxes: NodeListOf<HTMLInputElement> = null;
 
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/select-tree-element.ts b/Build/Sources/TypeScript/backend/form-engine/element/select-tree-element.ts
index 45e6c07526ec..acea708859b4 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/select-tree-element.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/select-tree-element.ts
@@ -98,7 +98,7 @@ export class SelectTreeElement {
     return TYPO3.settings.ajaxUrls.record_tree_data + '&' + new URLSearchParams(params);
   }
 
-  private selectNode = (evt: CustomEvent) => {
+  private readonly selectNode = (evt: CustomEvent) => {
     const node = evt.detail.node as TreeNode;
     this.updateAncestorsIndeterminateState(node);
     // check all nodes again, to ensure correct display of indeterminate state
@@ -112,7 +112,7 @@ export class SelectTreeElement {
    * It's done once after loading data.
    * Later indeterminate state is updated just for the subset of nodes
    */
-  private loadDataAfter = (evt: CustomEvent) => {
+  private readonly loadDataAfter = (evt: CustomEvent) => {
     this.tree.nodes = evt.detail.nodes.map((node: TreeNode) => {
       node.indeterminate = false;
       return node;
@@ -123,7 +123,7 @@ export class SelectTreeElement {
   /**
    * Sets a comma-separated list of selected nodes identifiers to configured input
    */
-  private saveCheckboxes = (): void => {
+  private readonly saveCheckboxes = (): void => {
     if (typeof this.recordField === 'undefined') {
       return;
     }
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/select-tree-toolbar.ts b/Build/Sources/TypeScript/backend/form-engine/element/select-tree-toolbar.ts
index c1ef7cd92b33..28b5469a5893 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/select-tree-toolbar.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/select-tree-toolbar.ts
@@ -20,7 +20,7 @@ import { TreeNode } from '../../tree/tree-node';
 @customElement('typo3-backend-form-selecttree-toolbar')
 export class SelectTreeToolbar extends LitElement {
   public tree: SelectTree;
-  private settings = {
+  private readonly settings = {
     collapseAllBtn: 'collapse-all-btn',
     expandAllBtn: 'expand-all-btn',
     searchInput: 'search-input',
diff --git a/Build/Sources/TypeScript/backend/form-engine/element/slug-element.ts b/Build/Sources/TypeScript/backend/form-engine/element/slug-element.ts
index 3c58f116344a..503b09a9c65a 100644
--- a/Build/Sources/TypeScript/backend/form-engine/element/slug-element.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/element/slug-element.ts
@@ -64,7 +64,7 @@ enum ProposalModes {
  *  - for existing records, we also check for conflicts, and check if we have subpages, or if we want to add a redirect (todo)
  */
 class SlugElement {
-  private options: FieldOptions = null;
+  private readonly options: FieldOptions = null;
   private fullElement: HTMLElement = null;
   private manuallyChanged: boolean = false;
   private readOnlyField: HTMLInputElement = null;
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/add-record.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/add-record.ts
index 06f59c64d938..8fd1723e7d72 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/add-record.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/add-record.ts
@@ -30,7 +30,7 @@ class AddRecord {
   /**
    * @param {Event} e
    */
-  private registerClickHandler = (e: Event): void => {
+  private readonly registerClickHandler = (e: Event): void => {
     e.preventDefault();
 
     FormEngine.preventFollowLinkIfNotSaved(this.controlElement.getAttribute('href'));
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/edit-popup.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/edit-popup.ts
index f0820fa77eb5..fec24b1ae032 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/edit-popup.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/edit-popup.ts
@@ -36,14 +36,14 @@ class EditPopup {
     });
   }
 
-  private registerChangeHandler = (): void => {
+  private readonly registerChangeHandler = (): void => {
     this.controlElement.classList.toggle('disabled', this.assignedFormField.options.selectedIndex === -1);
   };
 
   /**
    * @param {Event} e
    */
-  private registerClickHandler = (e: Event): void => {
+  private readonly registerClickHandler = (e: Event): void => {
     e.preventDefault();
 
     const values: Array<string> = [];
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/insert-clipboard.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/insert-clipboard.ts
index 0578ac248961..1a44f591a70d 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/insert-clipboard.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/insert-clipboard.ts
@@ -35,7 +35,7 @@ class InsertClipboard {
   /**
    * @param {Event} e
    */
-  private registerClickHandler = (e: Event): void => {
+  private readonly registerClickHandler = (e: Event): void => {
     e.preventDefault();
 
     const assignedElement: string = this.controlElement.dataset.element;
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/link-popup.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/link-popup.ts
index e2d0ea392ec2..5d54e97a2b92 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/link-popup.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/link-popup.ts
@@ -31,7 +31,7 @@ class LinkPopup {
   /**
    * @param {Event} e
    */
-  private handleControlClick = (e: Event): void => {
+  private readonly handleControlClick = (e: Event): void => {
     e.preventDefault();
 
     const itemName = this.controlElement.dataset.itemName;
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/list-module.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/list-module.ts
index ec9e412626d9..1fbbcfa176ae 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/list-module.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/list-module.ts
@@ -30,7 +30,7 @@ class ListModule {
   /**
    * @param {Event} e
    */
-  private registerClickHandler = (e: Event): void => {
+  private readonly registerClickHandler = (e: Event): void => {
     e.preventDefault();
 
     FormEngine.preventFollowLinkIfNotSaved(this.controlElement.getAttribute('href'));
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/password-generator.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/password-generator.ts
index 5cf040b83238..9f00e395551c 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/password-generator.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/password-generator.ts
@@ -31,7 +31,7 @@ interface PasswordRules {
  * Handles the "Generate Password" field control
  */
 class PasswordGenerator {
-  private securityUtility: SecurityUtility = null;
+  private readonly securityUtility: SecurityUtility = null;
   private controlElement: HTMLAnchorElement = null;
   private humanReadableField: HTMLInputElement = null;
   private hiddenField: HTMLInputElement = null;
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-control/reset-selection.ts b/Build/Sources/TypeScript/backend/form-engine/field-control/reset-selection.ts
index 0d7d3e61ae97..893ff2827118 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-control/reset-selection.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-control/reset-selection.ts
@@ -31,7 +31,7 @@ class ResetSelection {
   /**
    * @param {Event} e
    */
-  private registerClickHandler = (e: Event): void => {
+  private readonly registerClickHandler = (e: Event): void => {
     e.preventDefault();
 
     const itemName: string = this.controlElement.dataset.itemName;
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-picker.ts b/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-picker.ts
index ae08aadc89a7..c66602bb6f10 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-picker.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-picker.ts
@@ -45,7 +45,7 @@ export class ValuePicker extends HTMLElement {
     }
   }
 
-  private onChange = () => {
+  private readonly onChange = () => {
     this.setValue();
     this.valuePicker.selectedIndex = 0;
     this.valuePicker.blur();
diff --git a/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-slider.ts b/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-slider.ts
index f15ea5d9354c..36f4b3a8206b 100644
--- a/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-slider.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/field-wizard/value-slider.ts
@@ -39,7 +39,7 @@ export class ValueSlider extends HTMLElement {
     }
   }
 
-  private handleRangeChange = (e: Event): void => {
+  private readonly handleRangeChange = (e: Event): void => {
     const target = e.target as HTMLInputElement;
     this.updateValue(target);
     this.updateTooltipValue(target);
diff --git a/Build/Sources/TypeScript/backend/form-engine/request-update.ts b/Build/Sources/TypeScript/backend/form-engine/request-update.ts
index 299bd0bbb843..2671b3abe444 100644
--- a/Build/Sources/TypeScript/backend/form-engine/request-update.ts
+++ b/Build/Sources/TypeScript/backend/form-engine/request-update.ts
@@ -46,7 +46,7 @@ export class RequestUpdate extends LitElement {
     }
   }
 
-  private requestFormEngineUpdate = (): void => {
+  private readonly requestFormEngineUpdate = (): void => {
     const askForUpdate = this.mode === UpdateMode.ask;
     FormEngine.requestFormEngineUpdate(askForUpdate);
   };
diff --git a/Build/Sources/TypeScript/backend/global-event-handler.ts b/Build/Sources/TypeScript/backend/global-event-handler.ts
index 96e4992edd85..db564ac8c16e 100644
--- a/Build/Sources/TypeScript/backend/global-event-handler.ts
+++ b/Build/Sources/TypeScript/backend/global-event-handler.ts
@@ -47,7 +47,7 @@ type HTMLFormChildElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaE
  * </form>
  */
 class GlobalEventHandler {
-  private options = {
+  private readonly options = {
     onChangeSelector: '[data-global-event="change"]',
     onClickSelector: '[data-global-event="click"]',
     onSubmitSelector: 'form[data-global-event="submit"]',
diff --git a/Build/Sources/TypeScript/backend/image-manipulation.ts b/Build/Sources/TypeScript/backend/image-manipulation.ts
index 15ff78924488..e85cdea24bd5 100644
--- a/Build/Sources/TypeScript/backend/image-manipulation.ts
+++ b/Build/Sources/TypeScript/backend/image-manipulation.ts
@@ -67,17 +67,17 @@ class ImageManipulation {
   private activeCropVariantTrigger: HTMLElement;
   private cropInfo: HTMLElement;
   private imageOriginalSizeFactor: number;
-  private cropImageSelector: string = '#t3js-crop-image';
-  private coverAreaSelector: string = '.t3js-cropper-cover-area';
-  private cropInfoSelector: string = '.t3js-cropper-info-crop';
-  private focusAreaSelector: string = '#t3js-cropper-focus-area';
+  private readonly cropImageSelector: string = '#t3js-crop-image';
+  private readonly coverAreaSelector: string = '.t3js-cropper-cover-area';
+  private readonly cropInfoSelector: string = '.t3js-cropper-info-crop';
+  private readonly focusAreaSelector: string = '#t3js-cropper-focus-area';
   private focusAreaEl: DraggableResizableElement;
   // Initialize an empty object to prevent undefined cropBox error on modal load.
   private cropBox: HTMLElement;
   private cropper: Cropper;
   private currentCropVariant: CropVariant;
   private data: any;
-  private defaultFocusArea: Area = {
+  private readonly defaultFocusArea: Area = {
     height: 1 / 3,
     width: 1 / 3,
     x: 0,
@@ -379,7 +379,7 @@ class ImageManipulation {
   /**
    * @desc Internal cropper handler. Called when the cropper has been instantiated
    */
-  private cropBuiltHandler = (): void => {
+  private readonly cropBuiltHandler = (): void => {
     this.initialized = true;
 
     const imageData: Cropper.ImageData = this.cropper.getImageData();
@@ -437,7 +437,7 @@ class ImageManipulation {
   /**
    * @desc Internal cropper handler. Called when the cropping area is moving
    */
-  private cropMoveHandler = (e: CropperEvent): void => {
+  private readonly cropMoveHandler = (e: CropperEvent): void => {
     if (!this.initialized) {
       return;
     }
diff --git a/Build/Sources/TypeScript/backend/layout-module/paste.ts b/Build/Sources/TypeScript/backend/layout-module/paste.ts
index 0f6b1f96e9fc..b692c62c8440 100644
--- a/Build/Sources/TypeScript/backend/layout-module/paste.ts
+++ b/Build/Sources/TypeScript/backend/layout-module/paste.ts
@@ -36,7 +36,7 @@ class Paste {
   private readonly itemOnClipboardUid: number = 0;
   private readonly itemOnClipboardTitle: string = '';
   private readonly copyMode: string = '';
-  private elementIdentifier: string = '.t3js-page-ce';
+  private readonly elementIdentifier: string = '.t3js-page-ce';
   private pasteAfterLinkTemplate: string = '';
   private pasteIntoLinkTemplate: string = '';
 
diff --git a/Build/Sources/TypeScript/backend/link-browser.ts b/Build/Sources/TypeScript/backend/link-browser.ts
index bf8cf29416d6..0617a5cd608b 100644
--- a/Build/Sources/TypeScript/backend/link-browser.ts
+++ b/Build/Sources/TypeScript/backend/link-browser.ts
@@ -46,7 +46,7 @@ export interface LinkBrowserParameters {
  */
 class LinkBrowser {
   public parameters: LinkBrowserParameters;
-  private linkAttributeFields: LinkAttributes;
+  private readonly linkAttributeFields: LinkAttributes;
 
   constructor() {
     this.parameters = JSON.parse(document.body.dataset.linkbrowserParameters || '{}');
diff --git a/Build/Sources/TypeScript/backend/localization.ts b/Build/Sources/TypeScript/backend/localization.ts
index f8d109858fc0..6719fcc97a92 100644
--- a/Build/Sources/TypeScript/backend/localization.ts
+++ b/Build/Sources/TypeScript/backend/localization.ts
@@ -43,7 +43,7 @@ type SummaryRecord = {
 };
 
 class Localization {
-  private triggerButton: string = '.t3js-localize';
+  private readonly triggerButton: string = '.t3js-localize';
   private localizationMode: string = null;
   private sourceLanguage: number = null;
   private records: Array<any> = [];
diff --git a/Build/Sources/TypeScript/backend/login-refresh.ts b/Build/Sources/TypeScript/backend/login-refresh.ts
index b6ebfdec1651..65648d637378 100644
--- a/Build/Sources/TypeScript/backend/login-refresh.ts
+++ b/Build/Sources/TypeScript/backend/login-refresh.ts
@@ -39,7 +39,7 @@ interface RequestTokenResponseData {
  * @exports @typo3/backend/login-refresh
  */
 class LoginRefresh {
-  private options: any = {
+  private readonly options: any = {
     modalConfig: {
       backdrop: 'static',
     },
diff --git a/Build/Sources/TypeScript/backend/modal.ts b/Build/Sources/TypeScript/backend/modal.ts
index 0c970a41cc6a..ab8939fa5270 100644
--- a/Build/Sources/TypeScript/backend/modal.ts
+++ b/Build/Sources/TypeScript/backend/modal.ts
@@ -286,9 +286,9 @@ class Modal {
 
   // @todo: currentModal could be a getter method for the last element in this.instances
   public currentModal: ModalElement = null;
-  private instances: Array<ModalElement> = [];
+  private readonly instances: Array<ModalElement> = [];
 
-  private defaultConfiguration: Configuration = {
+  private readonly defaultConfiguration: Configuration = {
     type: Types.default,
     title: 'Information',
     content: 'No content provided, please check your <code>Modal</code> configuration.',
diff --git a/Build/Sources/TypeScript/backend/notification.ts b/Build/Sources/TypeScript/backend/notification.ts
index 94ba3092486d..dddadb3ee883 100644
--- a/Build/Sources/TypeScript/backend/notification.ts
+++ b/Build/Sources/TypeScript/backend/notification.ts
@@ -30,7 +30,7 @@ interface Action {
  * Notification API for the TYPO3 backend
  */
 class Notification {
-  private static duration: number = 5;
+  private static readonly duration: number = 5;
   private static messageContainer: HTMLElement = null;
 
   /**
diff --git a/Build/Sources/TypeScript/backend/page-link-handler.ts b/Build/Sources/TypeScript/backend/page-link-handler.ts
index def04ad9866b..02f8c3dee9b0 100644
--- a/Build/Sources/TypeScript/backend/page-link-handler.ts
+++ b/Build/Sources/TypeScript/backend/page-link-handler.ts
@@ -33,7 +33,7 @@ class PageLinkHandler {
     }).delegateTo(document, 'input.t3js-pageLink');
   }
 
-  private linkPageByTextfield = (): void => {
+  private readonly linkPageByTextfield = (): void => {
     const textField = document.getElementById('luid') as HTMLInputElement;
     let value = textField.value;
     if (!value) {
diff --git a/Build/Sources/TypeScript/backend/page-tree/page-tree-element.ts b/Build/Sources/TypeScript/backend/page-tree/page-tree-element.ts
index 442946628723..ea01ce87abda 100644
--- a/Build/Sources/TypeScript/backend/page-tree/page-tree-element.ts
+++ b/Build/Sources/TypeScript/backend/page-tree/page-tree-element.ts
@@ -336,15 +336,15 @@ export class PageTreeNavigationComponent extends LitElement {
     `;
   }
 
-  private refresh = (): void => {
+  private readonly refresh = (): void => {
     this.tree.refreshOrFilterTree();
   };
 
-  private setMountPoint = (e: CustomEvent): void => {
+  private readonly setMountPoint = (e: CustomEvent): void => {
     this.setTemporaryMountPoint(e.detail.pageId as number);
   };
 
-  private selectFirstNode = (): void => {
+  private readonly selectFirstNode = (): void => {
     this.tree.selectFirstNode();
   };
 
@@ -390,14 +390,14 @@ export class PageTreeNavigationComponent extends LitElement {
       });
   }
 
-  private toggleExpandState = (evt: CustomEvent): void => {
+  private readonly toggleExpandState = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (node) {
       Persistent.set('BackendComponents.States.Pagetree.stateHash.' + node.stateIdentifier, (node.expanded ? '1' : '0'));
     }
   };
 
-  private loadContent = (evt: CustomEvent): void => {
+  private readonly loadContent = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node?.checked) {
       return;
@@ -416,7 +416,7 @@ export class PageTreeNavigationComponent extends LitElement {
     top.TYPO3.Backend.ContentContainer.setUrl(contentUrl + 'id=' + node.identifier);
   };
 
-  private showContextMenu = (evt: CustomEvent): void => {
+  private readonly showContextMenu = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node) {
       return;
@@ -435,7 +435,7 @@ export class PageTreeNavigationComponent extends LitElement {
    * Event listener called for each loaded node,
    * here used to mark node remembered in ModuleState as selected
    */
-  private selectActiveNode = (evt: CustomEvent): void => {
+  private readonly selectActiveNode = (evt: CustomEvent): void => {
     const selectedNodeIdentifier = ModuleStateStorage.current('web').selection;
     const nodes = evt.detail.nodes as Array<TreeNode>;
     evt.detail.nodes = nodes.map((node: TreeNode) => {
@@ -701,8 +701,8 @@ class ToolbarDragHandler implements DragDropHandler {
   private readonly id: string = '';
   private readonly name: string = '';
   private readonly icon: string = '';
-  private dragDrop: PageTreeDragDrop;
-  private tree: EditablePageTree;
+  private readonly dragDrop: PageTreeDragDrop;
+  private readonly tree: EditablePageTree;
 
   constructor(item: any, tree: EditablePageTree, dragDrop: PageTreeDragDrop) {
     this.id = item.nodeType;
@@ -888,8 +888,8 @@ class PageTreeNodeDragHandler implements DragDropHandler {
    * @type {Selection}
    */
   private dropZoneDelete: null | TreeWrapperSelection<SVGGElement>;
-  private tree: any;
-  private dragDrop: PageTreeDragDrop;
+  private readonly tree: any;
+  private readonly dragDrop: PageTreeDragDrop;
   private nodeIsOverDelete: boolean = false;
 
   constructor(tree: any, dragDrop: PageTreeDragDrop) {
diff --git a/Build/Sources/TypeScript/backend/record-search.ts b/Build/Sources/TypeScript/backend/record-search.ts
index 106e59a726dd..722b521dd943 100644
--- a/Build/Sources/TypeScript/backend/record-search.ts
+++ b/Build/Sources/TypeScript/backend/record-search.ts
@@ -24,8 +24,8 @@ enum Selectors {
  * @exports @typo3/backend/record-search
  */
 class RecordSearch {
-  private searchField: HTMLInputElement = document.querySelector(Selectors.searchFieldSelector);
-  private activeSearch: boolean = this.searchField ? (this.searchField.value !== '') : false;
+  private readonly searchField: HTMLInputElement = document.querySelector(Selectors.searchFieldSelector);
+  private readonly activeSearch: boolean = this.searchField ? (this.searchField.value !== '') : false;
 
   constructor() {
     DocumentService.ready().then((): void => {
diff --git a/Build/Sources/TypeScript/backend/recordlist.ts b/Build/Sources/TypeScript/backend/recordlist.ts
index fcaccf606378..6bd978fa54ea 100644
--- a/Build/Sources/TypeScript/backend/recordlist.ts
+++ b/Build/Sources/TypeScript/backend/recordlist.ts
@@ -213,7 +213,7 @@ class Recordlist {
     window.location.href = editUrl;
   };
 
-  private disableButton = (event: JQueryEventObject): void => {
+  private readonly disableButton = (event: JQueryEventObject): void => {
     const $me = $(event.currentTarget);
 
     $me.prop('disable', true).addClass('disabled');
@@ -236,7 +236,7 @@ class Recordlist {
     }
   }
 
-  private deleteRow = (payload: DataHandlerEventPayload): void => {
+  private readonly deleteRow = (payload: DataHandlerEventPayload): void => {
     const $tableElement = $(`table[data-table="${payload.table}"]`);
     const $rowElement = $tableElement.find(`tr[data-uid="${payload.uid}"]`);
     const $panel = $tableElement.closest('.panel');
@@ -289,7 +289,7 @@ class Recordlist {
     });
   }
 
-  private registerPaginationEvents = (): void => {
+  private readonly registerPaginationEvents = (): void => {
     document.querySelectorAll('.t3js-recordlist-paging').forEach((trigger: HTMLInputElement) => {
       trigger.addEventListener('keyup', (e: KeyboardEvent) => {
         e.preventDefault();
diff --git a/Build/Sources/TypeScript/backend/storage/module-state-storage.ts b/Build/Sources/TypeScript/backend/storage/module-state-storage.ts
index 79c4103520f3..23d91299256d 100644
--- a/Build/Sources/TypeScript/backend/storage/module-state-storage.ts
+++ b/Build/Sources/TypeScript/backend/storage/module-state-storage.ts
@@ -33,7 +33,7 @@ interface CurrentState {
  * @exports @typo3/backend/storage/module-state-storage
  */
 export class ModuleStateStorage {
-  private static prefix = 't3-module-state-';
+  private static readonly prefix = 't3-module-state-';
 
   public static update(module: string, identifier: string|number, selected: boolean, mount?: string|number)
   {
diff --git a/Build/Sources/TypeScript/backend/toolbar/clear-cache-menu.ts b/Build/Sources/TypeScript/backend/toolbar/clear-cache-menu.ts
index 18fabbbe0ac7..df54aee31f66 100644
--- a/Build/Sources/TypeScript/backend/toolbar/clear-cache-menu.ts
+++ b/Build/Sources/TypeScript/backend/toolbar/clear-cache-menu.ts
@@ -38,7 +38,7 @@ class ClearCacheMenu {
    * Registers listeners for the icons inside the dropdown to trigger
    * the clear cache call
    */
-  private initializeEvents = (): void => {
+  private readonly initializeEvents = (): void => {
     const toolbarItemContainer = document.querySelector(Identifiers.containerSelector);
 
     new RegularEvent('click', (e: Event, menuItem: HTMLAnchorElement): void => {
diff --git a/Build/Sources/TypeScript/backend/toolbar/live-search.ts b/Build/Sources/TypeScript/backend/toolbar/live-search.ts
index 603abd241e90..350adc0f4e05 100644
--- a/Build/Sources/TypeScript/backend/toolbar/live-search.ts
+++ b/Build/Sources/TypeScript/backend/toolbar/live-search.ts
@@ -203,7 +203,7 @@ class LiveSearch {
     return composedSearchOptions;
   }
 
-  private search = async (formData: FormData): Promise<void> => {
+  private readonly search = async (formData: FormData): Promise<void> => {
     const query = formData.get('query').toString();
 
     if (query === '') {
diff --git a/Build/Sources/TypeScript/backend/toolbar/shortcut-menu.ts b/Build/Sources/TypeScript/backend/toolbar/shortcut-menu.ts
index 23b744c0d499..741ced2be10b 100644
--- a/Build/Sources/TypeScript/backend/toolbar/shortcut-menu.ts
+++ b/Build/Sources/TypeScript/backend/toolbar/shortcut-menu.ts
@@ -99,7 +99,7 @@ class ShortcutMenu {
     });
   }
 
-  private initializeEvents = (): void => {
+  private readonly initializeEvents = (): void => {
     const containerSelector = document.querySelector(Identifiers.containerSelector);
     new RegularEvent('click', (evt: Event, target: HTMLElement): void => {
       evt.preventDefault();
diff --git a/Build/Sources/TypeScript/backend/toolbar/system-information-menu.ts b/Build/Sources/TypeScript/backend/toolbar/system-information-menu.ts
index eb63c07d1161..8860f3fbd67e 100644
--- a/Build/Sources/TypeScript/backend/toolbar/system-information-menu.ts
+++ b/Build/Sources/TypeScript/backend/toolbar/system-information-menu.ts
@@ -92,7 +92,7 @@ class SystemInformationMenu {
     element.classList.toggle('hidden', !(data.count > 0));
   }
 
-  private updateMenu = (): void => {
+  private readonly updateMenu = (): void => {
     const toolbarItemIcon = document.querySelector(SystemInformationSelector.icon);
     const currentIcon = toolbarItemIcon.cloneNode(true);
 
diff --git a/Build/Sources/TypeScript/backend/tree/drag-drop.ts b/Build/Sources/TypeScript/backend/tree/drag-drop.ts
index 9d60af791425..87b625b5af96 100644
--- a/Build/Sources/TypeScript/backend/tree/drag-drop.ts
+++ b/Build/Sources/TypeScript/backend/tree/drag-drop.ts
@@ -66,8 +66,8 @@ export interface DragDropHandler {
  */
 export class DragDrop {
   protected tree: SvgTree;
-  private timeout: any = {};
-  private minimalDistance: number = 10;
+  private readonly timeout: any = {};
+  private readonly minimalDistance: number = 10;
 
   constructor(svgTree: SvgTree) {
     this.tree = svgTree;
diff --git a/Build/Sources/TypeScript/backend/tree/file-storage-browser.ts b/Build/Sources/TypeScript/backend/tree/file-storage-browser.ts
index b4455e5020e2..1e2470da436b 100644
--- a/Build/Sources/TypeScript/backend/tree/file-storage-browser.ts
+++ b/Build/Sources/TypeScript/backend/tree/file-storage-browser.ts
@@ -139,7 +139,7 @@ export class FileStorageBrowser extends LitElement {
     `;
   }
 
-  private selectActiveNode = (evt: CustomEvent): void => {
+  private readonly selectActiveNode = (evt: CustomEvent): void => {
     // Activate the current node
     const nodes = evt.detail.nodes as Array<TreeNode>;
     evt.detail.nodes = nodes.map((node: TreeNode) => {
@@ -150,7 +150,7 @@ export class FileStorageBrowser extends LitElement {
     });
   };
 
-  private toggleExpandState = (evt: CustomEvent): void => {
+  private readonly toggleExpandState = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (node) {
       Persistent.set('BackendComponents.States.FileStorageTree.stateHash.' + node.stateIdentifier, (node.expanded ? '1' : '0'));
@@ -160,7 +160,7 @@ export class FileStorageBrowser extends LitElement {
   /**
    * If a page is clicked, the content area needs to be updated
    */
-  private loadFolderDetails = (evt: CustomEvent): void => {
+  private readonly loadFolderDetails = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node.checked) {
       return;
diff --git a/Build/Sources/TypeScript/backend/tree/file-storage-tree-container.ts b/Build/Sources/TypeScript/backend/tree/file-storage-tree-container.ts
index eda2021ad4d7..36c6cef4cf71 100644
--- a/Build/Sources/TypeScript/backend/tree/file-storage-tree-container.ts
+++ b/Build/Sources/TypeScript/backend/tree/file-storage-tree-container.ts
@@ -62,7 +62,7 @@ export class EditableFileStorageTree extends FileStorageTree {
     return super.nodesUpdate.call(this, nodes).call(this.initializeDragForNode());
   }
 
-  private handleDragOver = (e: DragEvent): void => {
+  private readonly handleDragOver = (e: DragEvent): void => {
     const target = e.target as SVGElement;
     const node = this.getNodeFromElement(target);
     if (node) {
@@ -77,7 +77,7 @@ export class EditableFileStorageTree extends FileStorageTree {
     e.preventDefault();
   };
 
-  private handleDrop = (event: DragEvent): void => {
+  private readonly handleDrop = (event: DragEvent): void => {
     const target = event.target as Element;
     const element = target.closest('[data-state-id]') as SVGElement;
     const node = this.getNodeFromElement(element);
@@ -170,11 +170,11 @@ export class FileStorageTreeNavigationComponent extends LitElement {
     this.tree.addEventListener('typo3:svg-tree:nodes-prepared', this.selectActiveNode);
   }
 
-  private refresh = (): void => {
+  private readonly refresh = (): void => {
     this.tree.refreshOrFilterTree();
   };
 
-  private selectFirstNode = (): void => {
+  private readonly selectFirstNode = (): void => {
     const node = this.tree.nodes[0];
     if (node) {
       this.tree.selectNode(node, true);
@@ -182,7 +182,7 @@ export class FileStorageTreeNavigationComponent extends LitElement {
   };
 
   // event listener updating current tree state, this can be removed in TYPO3 v12
-  private treeUpdateRequested = (evt: CustomEvent): void => {
+  private readonly treeUpdateRequested = (evt: CustomEvent): void => {
     const identifier = encodeURIComponent(evt.detail.payload.identifier);
     const nodeToSelect = this.tree.nodes.filter((node: TreeNode) => { return node.identifier === identifier; })[0];
     if (nodeToSelect && this.tree.getSelectedNodes().filter((selectedNode: TreeNode) => { return selectedNode.identifier === nodeToSelect.identifier; }).length === 0) {
@@ -190,14 +190,14 @@ export class FileStorageTreeNavigationComponent extends LitElement {
     }
   };
 
-  private toggleExpandState = (evt: CustomEvent): void => {
+  private readonly toggleExpandState = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (node) {
       Persistent.set('BackendComponents.States.FileStorageTree.stateHash.' + node.stateIdentifier, (node.expanded ? '1' : '0'));
     }
   };
 
-  private loadContent = (evt: CustomEvent): void => {
+  private readonly loadContent = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node?.checked) {
       return;
@@ -217,7 +217,7 @@ export class FileStorageTreeNavigationComponent extends LitElement {
     top.TYPO3.Backend.ContentContainer.setUrl(contentUrl + 'id=' + node.identifier);
   };
 
-  private showContextMenu = (evt: CustomEvent): void => {
+  private readonly showContextMenu = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node) {
       return;
@@ -236,7 +236,7 @@ export class FileStorageTreeNavigationComponent extends LitElement {
    * Event listener called for each loaded node,
    * here used to mark node remembered in ModuleStateStorage as selected
    */
-  private selectActiveNode = (evt: CustomEvent): void => {
+  private readonly selectActiveNode = (evt: CustomEvent): void => {
     const selectedNodeIdentifier = ModuleStateStorage.current('file').selection;
     const nodes = evt.detail.nodes as Array<TreeNode>;
     evt.detail.nodes = nodes.map((node: TreeNode) => {
@@ -396,8 +396,8 @@ class FileStorageTreeNodeDragHandler implements DragDropHandler {
   public dragStarted: boolean = false;
   public startPageX: number = 0;
   public startPageY: number = 0;
-  private tree: FileStorageTree;
-  private actionHandler: FileStorageTreeActions;
+  private readonly tree: FileStorageTree;
+  private readonly actionHandler: FileStorageTreeActions;
 
   constructor(tree: FileStorageTree, actionHandler: FileStorageTreeActions) {
     this.tree = tree;
diff --git a/Build/Sources/TypeScript/backend/tree/page-browser.ts b/Build/Sources/TypeScript/backend/tree/page-browser.ts
index bc0b1b023251..0642d33988a1 100644
--- a/Build/Sources/TypeScript/backend/tree/page-browser.ts
+++ b/Build/Sources/TypeScript/backend/tree/page-browser.ts
@@ -210,7 +210,7 @@ export class PageBrowser extends LitElement {
     `;
   }
 
-  private selectActivePageInTree = (evt: CustomEvent): void => {
+  private readonly selectActivePageInTree = (evt: CustomEvent): void => {
     // Activate the current node
     const nodes = evt.detail.nodes as Array<TreeNode>;
     evt.detail.nodes = nodes.map((node: TreeNode) => {
@@ -221,7 +221,7 @@ export class PageBrowser extends LitElement {
     });
   };
 
-  private toggleExpandState = (evt: CustomEvent): void => {
+  private readonly toggleExpandState = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (node) {
       Persistent.set('BackendComponents.States.Pagetree.stateHash.' + node.stateIdentifier, (node.expanded ? '1' : '0'));
@@ -230,7 +230,7 @@ export class PageBrowser extends LitElement {
   /**
    * If a page is clicked, the content area needs to be updated
    */
-  private loadRecordsOfPage = (evt: CustomEvent): void => {
+  private readonly loadRecordsOfPage = (evt: CustomEvent): void => {
     const node = evt.detail.node as TreeNode;
     if (!node.checked) {
       return;
@@ -245,7 +245,7 @@ export class PageBrowser extends LitElement {
   };
 
 
-  private setMountPoint = (e: CustomEvent): void => {
+  private readonly setMountPoint = (e: CustomEvent): void => {
     this.setTemporaryMountPoint(e.detail.pageId as number);
   };
 
diff --git a/Build/Sources/TypeScript/backend/user-pass-login.ts b/Build/Sources/TypeScript/backend/user-pass-login.ts
index 9f9317b10d0f..61d8d888b630 100644
--- a/Build/Sources/TypeScript/backend/user-pass-login.ts
+++ b/Build/Sources/TypeScript/backend/user-pass-login.ts
@@ -122,7 +122,7 @@ class UserPassLogin {
     }
   };
 
-  private togglePasswordRevealer = (): void => {
+  private readonly togglePasswordRevealer = (): void => {
     const passwordField = document.querySelector(this.options.passwordField) as HTMLInputElement;
     const togglePassword = document.querySelector(this.options.togglePassword);
     togglePassword.classList.toggle('hidden', passwordField.value === '');
diff --git a/Build/Sources/TypeScript/backend/utility/collapse-state-persister.ts b/Build/Sources/TypeScript/backend/utility/collapse-state-persister.ts
index 6789458f1d8a..967d914a65d3 100644
--- a/Build/Sources/TypeScript/backend/utility/collapse-state-persister.ts
+++ b/Build/Sources/TypeScript/backend/utility/collapse-state-persister.ts
@@ -51,7 +51,7 @@ export class CollapseStatePersister {
   private searchField: HTMLInputElement|null = null;
   private searchForm: HTMLFormElement|null = null;
 
-  private stateCache: Map<string, PersistStateObject>;
+  private readonly stateCache: Map<string, PersistStateObject>;
 
   public constructor() {
     this.stateCache = new Map();
diff --git a/Build/Sources/TypeScript/backend/viewport/resizable-navigation.ts b/Build/Sources/TypeScript/backend/viewport/resizable-navigation.ts
index 4bc020d97341..6a241dbab4a4 100644
--- a/Build/Sources/TypeScript/backend/viewport/resizable-navigation.ts
+++ b/Build/Sources/TypeScript/backend/viewport/resizable-navigation.ts
@@ -74,7 +74,7 @@ export class ResizableNavigation extends LitElement {
     `;
   }
 
-  private toggleNavigation = (event: MouseEvent | TouchEvent) => {
+  private readonly toggleNavigation = (event: MouseEvent | TouchEvent) => {
     if (event instanceof MouseEvent && event.button === 2) {
       return;
     }
@@ -82,7 +82,7 @@ export class ResizableNavigation extends LitElement {
     this.parentContainer.classList.toggle('scaffold-content-navigation-expanded');
   };
 
-  private fallbackNavigationSizeIfNeeded = (event: UIEvent) => {
+  private readonly fallbackNavigationSizeIfNeeded = (event: UIEvent) => {
     const window = <Window>event.currentTarget;
     if (this.getNavigationWidth() === 0) {
       return;
@@ -92,20 +92,20 @@ export class ResizableNavigation extends LitElement {
     }
   };
 
-  private handleMouseMove = (event: MouseEvent) => {
+  private readonly handleMouseMove = (event: MouseEvent) => {
     this.resizeNavigation(<number>event.clientX);
   };
 
-  private handleTouchMove = (event: TouchEvent) => {
+  private readonly handleTouchMove = (event: TouchEvent) => {
     this.resizeNavigation(<number>event.changedTouches[0].clientX);
   };
 
-  private resizeNavigation = (position: number) => {
+  private readonly resizeNavigation = (position: number) => {
     const width = Math.round(position) - Math.round(this.getNavigationPosition().left);
     this.setNavigationWidth(width);
   };
 
-  private startResizeNavigation = (event: MouseEvent | TouchEvent) => {
+  private readonly startResizeNavigation = (event: MouseEvent | TouchEvent) => {
     if (event instanceof MouseEvent && event.button === 2) {
       return;
     }
@@ -117,7 +117,7 @@ export class ResizableNavigation extends LitElement {
     document.addEventListener('touchend', this.stopResizeNavigation, false);
   };
 
-  private stopResizeNavigation = () => {
+  private readonly stopResizeNavigation = () => {
     this.resizing = false;
     document.removeEventListener('mousemove', this.handleMouseMove, false);
     document.removeEventListener('mouseup', this.stopResizeNavigation, false);
diff --git a/Build/Sources/TypeScript/beuser/permissions.ts b/Build/Sources/TypeScript/beuser/permissions.ts
index 9a321c464f8b..f371624573bd 100644
--- a/Build/Sources/TypeScript/beuser/permissions.ts
+++ b/Build/Sources/TypeScript/beuser/permissions.ts
@@ -20,12 +20,12 @@ import AjaxRequest from '@typo3/core/ajax/ajax-request';
  * Javascript functions regarding the permissions module
  */
 class Permissions {
-  private options: any = {
+  private readonly options: any = {
     containerSelector: '#typo3-permissionList',
     editControllerSelector: '#PermissionControllerEdit',
   };
 
-  private ajaxUrl: string = TYPO3.settings.ajaxUrls.user_access_permissions;
+  private readonly ajaxUrl: string = TYPO3.settings.ajaxUrls.user_access_permissions;
 
   constructor() {
     this.initializeCheckboxGroups();
diff --git a/Build/Sources/TypeScript/core/ajax/ajax-request.ts b/Build/Sources/TypeScript/core/ajax/ajax-request.ts
index 4af27441f667..bb905f630076 100644
--- a/Build/Sources/TypeScript/core/ajax/ajax-request.ts
+++ b/Build/Sources/TypeScript/core/ajax/ajax-request.ts
@@ -30,7 +30,7 @@ import { GenericKeyValue, InputTransformer } from './input-transformer';
  * // `$value = json_decode((string)ServerRequest::getBody(), true)['item']['first']`
  */
 class AjaxRequest {
-  private static defaultOptions: RequestInit = {
+  private static readonly defaultOptions: RequestInit = {
     credentials: 'same-origin'
   };
 
diff --git a/Build/Sources/TypeScript/core/java-script-item-processor.ts b/Build/Sources/TypeScript/core/java-script-item-processor.ts
index 4f470f1b80b7..bfce48f8423c 100644
--- a/Build/Sources/TypeScript/core/java-script-item-processor.ts
+++ b/Build/Sources/TypeScript/core/java-script-item-processor.ts
@@ -171,7 +171,7 @@ function mergeRecursive(target: { [key: string]: any }, source: { [key: string]:
 }
 
 export class JavaScriptItemProcessor {
-  private invokableNames: string[] = ['globalAssignment', 'javaScriptModuleInstruction'];
+  private readonly invokableNames: string[] = ['globalAssignment', 'javaScriptModuleInstruction'];
 
   /**
    * Processes multiple items and delegates to handlers
diff --git a/Build/Sources/TypeScript/extensionmanager/repository.ts b/Build/Sources/TypeScript/extensionmanager/repository.ts
index 5cb7b762d30d..e639485fe22b 100644
--- a/Build/Sources/TypeScript/extensionmanager/repository.ts
+++ b/Build/Sources/TypeScript/extensionmanager/repository.ts
@@ -68,7 +68,7 @@ class Repository {
     }).delegateTo(document, '.downloadFromTer form.download button[type=submit]');
   }
 
-  private getDependencies = async(response: AjaxResponse): Promise<void> => {
+  private readonly getDependencies = async(response: AjaxResponse): Promise<void> => {
     const data = await response.resolve();
 
     NProgress.done();
diff --git a/Build/Sources/TypeScript/filelist/browse-files.ts b/Build/Sources/TypeScript/filelist/browse-files.ts
index f3a9d929a60d..2af23002f362 100644
--- a/Build/Sources/TypeScript/filelist/browse-files.ts
+++ b/Build/Sources/TypeScript/filelist/browse-files.ts
@@ -88,7 +88,7 @@ class BrowseFiles {
       });
   }
 
-  private importSelection = (event: CustomEvent): void => {
+  private readonly importSelection = (event: CustomEvent): void => {
     event.preventDefault();
     const target: HTMLElement = event.target as HTMLElement;
     const items: NodeListOf<HTMLInputElement> = (event.detail as ActionEventDetails).checkboxes;
diff --git a/Build/Sources/TypeScript/filelist/browse-folders.ts b/Build/Sources/TypeScript/filelist/browse-folders.ts
index 76a058129ca0..3173e7f39023 100644
--- a/Build/Sources/TypeScript/filelist/browse-folders.ts
+++ b/Build/Sources/TypeScript/filelist/browse-folders.ts
@@ -64,7 +64,7 @@ class BrowseFolders {
     );
   }
 
-  private importSelection = (event: CustomEvent): void => {
+  private readonly importSelection = (event: CustomEvent): void => {
     event.preventDefault();
     const items: NodeListOf<HTMLInputElement> = (event.detail as ActionEventDetails).checkboxes;
     if (!items.length) {
diff --git a/Build/Sources/TypeScript/filelist/file-list-dragdrop.ts b/Build/Sources/TypeScript/filelist/file-list-dragdrop.ts
index 90ccf81bee69..3ddb20f7cfe4 100644
--- a/Build/Sources/TypeScript/filelist/file-list-dragdrop.ts
+++ b/Build/Sources/TypeScript/filelist/file-list-dragdrop.ts
@@ -30,10 +30,10 @@ export enum FileListDragDropEvent {
 type Coordinates = { left: number, top: number };
 
 class FileListDragDrop {
-  private dragPreviewId: string = 'dragpreview';
-  private rootDocument: Document;
+  private readonly dragPreviewId: string = 'dragpreview';
+  private readonly rootDocument: Document;
   private currentAnimationRequestId: number | null = null;
-  private previewSize: number = 32;
+  private readonly previewSize: number = 32;
 
   constructor() {
     this.rootDocument = top.document;
diff --git a/Build/Sources/TypeScript/filelist/file-list.ts b/Build/Sources/TypeScript/filelist/file-list.ts
index 68c743b6ae9e..8a5606b48ab9 100644
--- a/Build/Sources/TypeScript/filelist/file-list.ts
+++ b/Build/Sources/TypeScript/filelist/file-list.ts
@@ -279,7 +279,7 @@ export default class Filelist {
     }
   }
 
-  private downloadFilesAndFolders = (event: CustomEvent): void => {
+  private readonly downloadFilesAndFolders = (event: CustomEvent): void => {
     event.preventDefault();
     const target: HTMLElement = event.target as HTMLElement;
     const eventDetails: ActionEventDetails = (event.detail as ActionEventDetails);
diff --git a/Build/Sources/TypeScript/form/backend/form-editor/core.ts b/Build/Sources/TypeScript/form/backend/form-editor/core.ts
index 336c66dfd43e..096f85dbb17a 100644
--- a/Build/Sources/TypeScript/form/backend/form-editor/core.ts
+++ b/Build/Sources/TypeScript/form/backend/form-editor/core.ts
@@ -738,7 +738,7 @@ function extendModel<D extends object, T extends ModelData<D>>(
 
 export class Model<D extends object, T extends ModelData<D>> {
 
-  private objectData: T = <T>{};
+  private readonly objectData: T = <T>{};
 
   private publisherTopics: {[key: string]: string[]} = {};
 
@@ -1872,7 +1872,7 @@ export class DataBackend {
 export class ApplicationStateStack {
   private stackSize: number = 10;
   private stackPointer: number = 0;
-  private stack: ApplicationState[] = [];
+  private readonly stack: ApplicationState[] = [];
 
   /**
    * @publish core/applicationState/add
diff --git a/Build/Sources/TypeScript/form/backend/form-manager.ts b/Build/Sources/TypeScript/form/backend/form-manager.ts
index 496893bb23fa..0f6be1a07b18 100644
--- a/Build/Sources/TypeScript/form/backend/form-manager.ts
+++ b/Build/Sources/TypeScript/form/backend/form-manager.ts
@@ -56,7 +56,7 @@ export function assert(test: boolean|(() => boolean), message: string, messageCo
 export class FormManager {
   private isRunning: boolean = false;
   private configuration: FormManagerConfiguration;
-  private viewModel: ViewModel;
+  private readonly viewModel: ViewModel;
 
   public constructor(
     configuration: FormManagerConfiguration,
diff --git a/Build/Sources/TypeScript/install/ajax/ajax-queue.ts b/Build/Sources/TypeScript/install/ajax/ajax-queue.ts
index 96ef87b3bd0f..16a8862bcf6f 100644
--- a/Build/Sources/TypeScript/install/ajax/ajax-queue.ts
+++ b/Build/Sources/TypeScript/install/ajax/ajax-queue.ts
@@ -30,7 +30,7 @@ interface Payload {
 class AjaxQueue {
   private requests: Array<AjaxRequest> = [];
   private requestCount: number = 0;
-  private threshold: number = 5;
+  private readonly threshold: number = 5;
   private queue: Array<Payload> = [];
 
   public add(payload: Payload): void {
diff --git a/Build/Sources/TypeScript/install/installer.ts b/Build/Sources/TypeScript/install/installer.ts
index 851bcb45b04c..fc58e91dd311 100644
--- a/Build/Sources/TypeScript/install/installer.ts
+++ b/Build/Sources/TypeScript/install/installer.ts
@@ -26,14 +26,14 @@ import MessageInterface from '@typo3/install/message-interface';
  * Walk through the installation process of TYPO3
  */
 class Installer {
-  private selectorBody: string = '.t3js-body';
-  private selectorModuleContent: string = '.t3js-module-content';
-  private selectorMainContent: string = '.t3js-installer-content';
-  private selectorProgressBar: string = '.t3js-installer-progress';
-  private selectorProgressBarSteps: string = '.t3js-installer-progress-steps';
-  private selectorDatabaseConnectOutput: string = '.t3js-installer-databaseConnect-output';
-  private selectorDatabaseSelectOutput: string = '.t3js-installer-databaseSelect-output';
-  private selectorDatabaseDataOutput: string = '.t3js-installer-databaseData-output';
+  private readonly selectorBody: string = '.t3js-body';
+  private readonly selectorModuleContent: string = '.t3js-module-content';
+  private readonly selectorMainContent: string = '.t3js-installer-content';
+  private readonly selectorProgressBar: string = '.t3js-installer-progress';
+  private readonly selectorProgressBarSteps: string = '.t3js-installer-progress-steps';
+  private readonly selectorDatabaseConnectOutput: string = '.t3js-installer-databaseConnect-output';
+  private readonly selectorDatabaseSelectOutput: string = '.t3js-installer-databaseSelect-output';
+  private readonly selectorDatabaseDataOutput: string = '.t3js-installer-databaseData-output';
 
   constructor() {
     this.initializeEvents();
diff --git a/Build/Sources/TypeScript/install/module/environment/environment-check.ts b/Build/Sources/TypeScript/install/module/environment/environment-check.ts
index 89c89fb0f0d0..39a38c68ff57 100644
--- a/Build/Sources/TypeScript/install/module/environment/environment-check.ts
+++ b/Build/Sources/TypeScript/install/module/environment/environment-check.ts
@@ -41,9 +41,9 @@ interface EnvironmentCheckResponse {
  * Module: @typo3/install/environment-check
  */
 class EnvironmentCheck extends AbstractInteractableModule {
-  private selectorGridderBadge: string = '.t3js-environmentCheck-badge';
-  private selectorExecuteTrigger: string = '.t3js-environmentCheck-execute';
-  private selectorOutputContainer: string = '.t3js-environmentCheck-output';
+  private readonly selectorGridderBadge: string = '.t3js-environmentCheck-badge';
+  private readonly selectorExecuteTrigger: string = '.t3js-environmentCheck-execute';
+  private readonly selectorOutputContainer: string = '.t3js-environmentCheck-output';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/environment/folder-structure.ts b/Build/Sources/TypeScript/install/module/environment/folder-structure.ts
index 09346f3f860d..d88b44e09d8f 100644
--- a/Build/Sources/TypeScript/install/module/environment/folder-structure.ts
+++ b/Build/Sources/TypeScript/install/module/environment/folder-structure.ts
@@ -27,14 +27,14 @@ import Router from '../../router';
  * Module: @typo3/install/module/folder-structure
  */
 class FolderStructure extends AbstractInteractableModule {
-  private selectorGridderBadge: string = '.t3js-folderStructure-badge';
-  private selectorOutputContainer: string = '.t3js-folderStructure-output';
-  private selectorErrorContainer: string = '.t3js-folderStructure-errors';
-  private selectorErrorList: string = '.t3js-folderStructure-errors-list';
-  private selectorErrorFixTrigger: string = '.t3js-folderStructure-errors-fix';
-  private selectorOkContainer: string = '.t3js-folderStructure-ok';
-  private selectorOkList: string = '.t3js-folderStructure-ok-list';
-  private selectorPermissionContainer: string = '.t3js-folderStructure-permissions';
+  private readonly selectorGridderBadge: string = '.t3js-folderStructure-badge';
+  private readonly selectorOutputContainer: string = '.t3js-folderStructure-output';
+  private readonly selectorErrorContainer: string = '.t3js-folderStructure-errors';
+  private readonly selectorErrorList: string = '.t3js-folderStructure-errors-list';
+  private readonly selectorErrorFixTrigger: string = '.t3js-folderStructure-errors-fix';
+  private readonly selectorOkContainer: string = '.t3js-folderStructure-ok';
+  private readonly selectorOkList: string = '.t3js-folderStructure-ok-list';
+  private readonly selectorPermissionContainer: string = '.t3js-folderStructure-permissions';
 
   private static removeLoadingMessage($container: JQuery): void {
     $container.find('.alert-loading').remove();
diff --git a/Build/Sources/TypeScript/install/module/environment/image-processing.ts b/Build/Sources/TypeScript/install/module/environment/image-processing.ts
index d065ab219fd7..bfa595886962 100644
--- a/Build/Sources/TypeScript/install/module/environment/image-processing.ts
+++ b/Build/Sources/TypeScript/install/module/environment/image-processing.ts
@@ -27,12 +27,12 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/image-processing
  */
 class ImageProcessing extends AbstractInteractableModule {
-  private selectorExecuteTrigger: string = '.t3js-imageProcessing-execute';
-  private selectorTestContainer: string = '.t3js-imageProcessing-twinContainer';
-  private selectorTwinImageTemplate: string = '.t3js-imageProcessing-twinImage-template';
-  private selectorCommandContainer: string = '.t3js-imageProcessing-command';
-  private selectorCommandText: string = '.t3js-imageProcessing-command-text';
-  private selectorTwinImages: string = '.t3js-imageProcessing-images';
+  private readonly selectorExecuteTrigger: string = '.t3js-imageProcessing-execute';
+  private readonly selectorTestContainer: string = '.t3js-imageProcessing-twinContainer';
+  private readonly selectorTwinImageTemplate: string = '.t3js-imageProcessing-twinImage-template';
+  private readonly selectorCommandContainer: string = '.t3js-imageProcessing-command';
+  private readonly selectorCommandText: string = '.t3js-imageProcessing-command-text';
+  private readonly selectorTwinImages: string = '.t3js-imageProcessing-images';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/environment/mail-test.ts b/Build/Sources/TypeScript/install/module/environment/mail-test.ts
index 71e8d35b0f3d..7f28d7f90f1c 100644
--- a/Build/Sources/TypeScript/install/module/environment/mail-test.ts
+++ b/Build/Sources/TypeScript/install/module/environment/mail-test.ts
@@ -27,8 +27,8 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/create-admin
  */
 class MailTest extends AbstractInteractableModule {
-  private selectorOutputContainer: string = '.t3js-mailTest-output';
-  private selectorMailTestButton: string = '.t3js-mailTest-execute';
+  private readonly selectorOutputContainer: string = '.t3js-mailTest-output';
+  private readonly selectorMailTestButton: string = '.t3js-mailTest-execute';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts b/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts
index ef0422820139..e8243d79005f 100644
--- a/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts
+++ b/Build/Sources/TypeScript/install/module/maintenance/clear-tables.ts
@@ -24,14 +24,14 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/clear-tables
  */
 class ClearTables extends AbstractInteractableModule {
-  private selectorClearTrigger: string = '.t3js-clearTables-clear';
-  private selectorStatsTrigger: string = '.t3js-clearTables-stats';
-  private selectorOutputContainer: string = '.t3js-clearTables-output';
-  private selectorStatContainer: string = '.t3js-clearTables-stat-container';
-  private selectorStatTemplate: string = '.t3js-clearTables-stat-template';
-  private selectorStatDescription: string = '.t3js-clearTables-stat-description';
-  private selectorStatRows: string = '.t3js-clearTables-stat-rows';
-  private selectorStatName: string = '.t3js-clearTables-stat-name';
+  private readonly selectorClearTrigger: string = '.t3js-clearTables-clear';
+  private readonly selectorStatsTrigger: string = '.t3js-clearTables-stats';
+  private readonly selectorOutputContainer: string = '.t3js-clearTables-output';
+  private readonly selectorStatContainer: string = '.t3js-clearTables-stat-container';
+  private readonly selectorStatTemplate: string = '.t3js-clearTables-stat-template';
+  private readonly selectorStatDescription: string = '.t3js-clearTables-stat-description';
+  private readonly selectorStatRows: string = '.t3js-clearTables-stat-rows';
+  private readonly selectorStatName: string = '.t3js-clearTables-stat-name';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts b/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts
index 65d4d32b9a87..3f5115979a00 100644
--- a/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts
+++ b/Build/Sources/TypeScript/install/module/maintenance/clear-typo3temp-files.ts
@@ -24,13 +24,13 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/clear-typo3temp-files
  */
 class ClearTypo3tempFiles extends AbstractInteractableModule {
-  private selectorDeleteTrigger: string = '.t3js-clearTypo3temp-delete';
-  private selectorOutputContainer: string = '.t3js-clearTypo3temp-output';
-  private selectorStatContainer: string = '.t3js-clearTypo3temp-stat-container';
-  private selectorStatsTrigger: string = '.t3js-clearTypo3temp-stats';
-  private selectorStatTemplate: string = '.t3js-clearTypo3temp-stat-template';
-  private selectorStatNumberOfFiles: string = '.t3js-clearTypo3temp-stat-numberOfFiles';
-  private selectorStatDirectory: string = '.t3js-clearTypo3temp-stat-directory';
+  private readonly selectorDeleteTrigger: string = '.t3js-clearTypo3temp-delete';
+  private readonly selectorOutputContainer: string = '.t3js-clearTypo3temp-output';
+  private readonly selectorStatContainer: string = '.t3js-clearTypo3temp-stat-container';
+  private readonly selectorStatsTrigger: string = '.t3js-clearTypo3temp-stats';
+  private readonly selectorStatTemplate: string = '.t3js-clearTypo3temp-stat-template';
+  private readonly selectorStatNumberOfFiles: string = '.t3js-clearTypo3temp-stat-numberOfFiles';
+  private readonly selectorStatDirectory: string = '.t3js-clearTypo3temp-stat-directory';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/maintenance/create-admin.ts b/Build/Sources/TypeScript/install/module/maintenance/create-admin.ts
index 5dec8a22d138..2e6a9aee2d4f 100644
--- a/Build/Sources/TypeScript/install/module/maintenance/create-admin.ts
+++ b/Build/Sources/TypeScript/install/module/maintenance/create-admin.ts
@@ -24,7 +24,7 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/create-admin
  */
 class CreateAdmin extends AbstractInteractableModule {
-  private selectorAdminCreateButton: string = '.t3js-createAdmin-create';
+  private readonly selectorAdminCreateButton: string = '.t3js-createAdmin-create';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts b/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts
index c6b16258059b..f0856286d466 100644
--- a/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts
+++ b/Build/Sources/TypeScript/install/module/maintenance/database-analyzer.ts
@@ -27,12 +27,12 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/database-analyzer
  */
 class DatabaseAnalyzer extends AbstractInteractableModule {
-  private selectorAnalyzeTrigger: string = '.t3js-databaseAnalyzer-analyze';
-  private selectorExecuteTrigger: string = '.t3js-databaseAnalyzer-execute';
-  private selectorOutputContainer: string = '.t3js-databaseAnalyzer-output';
-  private selectorSuggestionBlock: string = '.t3js-databaseAnalyzer-suggestion-block';
-  private selectorSuggestionList: string = '.t3js-databaseAnalyzer-suggestion-list';
-  private selectorSuggestionLineTemplate: string = '.t3js-databaseAnalyzer-suggestion-line-template';
+  private readonly selectorAnalyzeTrigger: string = '.t3js-databaseAnalyzer-analyze';
+  private readonly selectorExecuteTrigger: string = '.t3js-databaseAnalyzer-execute';
+  private readonly selectorOutputContainer: string = '.t3js-databaseAnalyzer-output';
+  private readonly selectorSuggestionBlock: string = '.t3js-databaseAnalyzer-suggestion-block';
+  private readonly selectorSuggestionList: string = '.t3js-databaseAnalyzer-suggestion-list';
+  private readonly selectorSuggestionLineTemplate: string = '.t3js-databaseAnalyzer-suggestion-line-template';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/maintenance/language-packs.ts b/Build/Sources/TypeScript/install/module/maintenance/language-packs.ts
index bd836e5c1843..c3caddcdc8d9 100644
--- a/Build/Sources/TypeScript/install/module/maintenance/language-packs.ts
+++ b/Build/Sources/TypeScript/install/module/maintenance/language-packs.ts
@@ -28,17 +28,17 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/language-packs
  */
 class LanguagePacks extends AbstractInteractableModule {
-  private selectorOutputContainer: string = '.t3js-languagePacks-output';
-  private selectorContentContainer: string = '.t3js-languagePacks-mainContent';
-  private selectorActivateLanguage: string = '.t3js-languagePacks-activateLanguage';
-  private selectorActivateLanguageIcon: string = '#t3js-languagePacks-activate-icon';
-  private selectorAddLanguageToggle: string = '.t3js-languagePacks-addLanguage-toggle';
-  private selectorLanguageInactive: string = '.t3js-languagePacks-inactive';
-  private selectorDeactivateLanguage: string = '.t3js-languagePacks-deactivateLanguage';
-  private selectorDeactivateLanguageIcon: string = '#t3js-languagePacks-deactivate-icon';
-  private selectorUpdate: string = '.t3js-languagePacks-update';
-  private selectorLanguageUpdateIcon: string = '#t3js-languagePacks-languageUpdate-icon';
-  private selectorNotifications: string = '.t3js-languagePacks-notifications';
+  private readonly selectorOutputContainer: string = '.t3js-languagePacks-output';
+  private readonly selectorContentContainer: string = '.t3js-languagePacks-mainContent';
+  private readonly selectorActivateLanguage: string = '.t3js-languagePacks-activateLanguage';
+  private readonly selectorActivateLanguageIcon: string = '#t3js-languagePacks-activate-icon';
+  private readonly selectorAddLanguageToggle: string = '.t3js-languagePacks-addLanguage-toggle';
+  private readonly selectorLanguageInactive: string = '.t3js-languagePacks-inactive';
+  private readonly selectorDeactivateLanguage: string = '.t3js-languagePacks-deactivateLanguage';
+  private readonly selectorDeactivateLanguageIcon: string = '#t3js-languagePacks-deactivate-icon';
+  private readonly selectorUpdate: string = '.t3js-languagePacks-update';
+  private readonly selectorLanguageUpdateIcon: string = '#t3js-languagePacks-languageUpdate-icon';
+  private readonly selectorNotifications: string = '.t3js-languagePacks-notifications';
 
   private activeLanguages: string[] = [];
   private activeExtensions: string[] = [];
diff --git a/Build/Sources/TypeScript/install/module/settings/change-install-tool-password.ts b/Build/Sources/TypeScript/install/module/settings/change-install-tool-password.ts
index 527b81939612..678c3e6852a6 100644
--- a/Build/Sources/TypeScript/install/module/settings/change-install-tool-password.ts
+++ b/Build/Sources/TypeScript/install/module/settings/change-install-tool-password.ts
@@ -24,7 +24,7 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/change-install-tool-password
  */
 class ChangeInstallToolPassword extends AbstractInteractableModule {
-  private selectorChangeButton: string = '.t3js-changeInstallToolPassword-change';
+  private readonly selectorChangeButton: string = '.t3js-changeInstallToolPassword-change';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/settings/extension-configuration.ts b/Build/Sources/TypeScript/install/module/settings/extension-configuration.ts
index a38bf274f5b3..78fc625b865b 100644
--- a/Build/Sources/TypeScript/install/module/settings/extension-configuration.ts
+++ b/Build/Sources/TypeScript/install/module/settings/extension-configuration.ts
@@ -29,8 +29,8 @@ import RegularEvent from '@typo3/core/event/regular-event';
  * Module: @typo3/install/module/extension-configuration
  */
 class ExtensionConfiguration extends AbstractInteractableModule {
-  private selectorFormListener: string = '.t3js-extensionConfiguration-form';
-  private selectorSearchInput: string = '.t3js-extensionConfiguration-search';
+  private readonly selectorFormListener: string = '.t3js-extensionConfiguration-form';
+  private readonly selectorSearchInput: string = '.t3js-extensionConfiguration-search';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/settings/features.ts b/Build/Sources/TypeScript/install/module/settings/features.ts
index 7fa062358aa9..76f86f648f18 100644
--- a/Build/Sources/TypeScript/install/module/settings/features.ts
+++ b/Build/Sources/TypeScript/install/module/settings/features.ts
@@ -23,7 +23,7 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/features
  */
 class Features extends AbstractInteractableModule {
-  private selectorSaveTrigger: string = '.t3js-features-save';
+  private readonly selectorSaveTrigger: string = '.t3js-features-save';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/settings/local-configuration.ts b/Build/Sources/TypeScript/install/module/settings/local-configuration.ts
index 86c527f85fd9..edebf47d885c 100644
--- a/Build/Sources/TypeScript/install/module/settings/local-configuration.ts
+++ b/Build/Sources/TypeScript/install/module/settings/local-configuration.ts
@@ -27,10 +27,10 @@ import MessageInterface from '@typo3/install/message-interface';
  */
 class LocalConfiguration extends AbstractInteractableModule {
   private searchInput: HTMLInputElement;
-  private selectorItem: string = '.t3js-localConfiguration-item';
-  private selectorToggleAllTrigger: string = '.t3js-localConfiguration-toggleAll';
-  private selectorWriteTrigger: string = '.t3js-localConfiguration-write';
-  private selectorSearchTrigger: string = '.t3js-localConfiguration-search';
+  private readonly selectorItem: string = '.t3js-localConfiguration-item';
+  private readonly selectorToggleAllTrigger: string = '.t3js-localConfiguration-toggleAll';
+  private readonly selectorWriteTrigger: string = '.t3js-localConfiguration-write';
+  private readonly selectorSearchTrigger: string = '.t3js-localConfiguration-search';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/settings/presets.ts b/Build/Sources/TypeScript/install/module/settings/presets.ts
index 2f1aa20142d0..10687d4369b0 100644
--- a/Build/Sources/TypeScript/install/module/settings/presets.ts
+++ b/Build/Sources/TypeScript/install/module/settings/presets.ts
@@ -25,9 +25,9 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/presets
  */
 class Presets extends AbstractInteractableModule {
-  private selectorActivateTrigger: string = '.t3js-presets-activate';
-  private selectorImageExecutable: string = '.t3js-presets-image-executable';
-  private selectorImageExecutableTrigger: string = '.t3js-presets-image-executable-trigger';
+  private readonly selectorActivateTrigger: string = '.t3js-presets-activate';
+  private readonly selectorImageExecutable: string = '.t3js-presets-image-executable';
+  private readonly selectorImageExecutableTrigger: string = '.t3js-presets-image-executable-trigger';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/settings/system-maintainer.ts b/Build/Sources/TypeScript/install/module/settings/system-maintainer.ts
index 6d940e00ede8..8087b89b793d 100644
--- a/Build/Sources/TypeScript/install/module/settings/system-maintainer.ts
+++ b/Build/Sources/TypeScript/install/module/settings/system-maintainer.ts
@@ -41,9 +41,9 @@ type SystemMaintainerListResponse = {
  * Module: @typo3/install/module/system-maintainer
  */
 class SystemMaintainer extends AbstractInteractableModule {
-  private selectorWriteTrigger: string = '.t3js-systemMaintainer-write';
-  private selectorChosenContainer: string = '.t3js-systemMaintainer-chosen';
-  private selectorChosenField: string = '.t3js-systemMaintainer-chosen-select';
+  private readonly selectorWriteTrigger: string = '.t3js-systemMaintainer-write';
+  private readonly selectorChosenContainer: string = '.t3js-systemMaintainer-chosen';
+  private readonly selectorChosenField: string = '.t3js-systemMaintainer-chosen-select';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/core-update.ts b/Build/Sources/TypeScript/install/module/upgrade/core-update.ts
index e4947ea8688f..7f7611fff4ca 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/core-update.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/core-update.ts
@@ -32,7 +32,7 @@ interface ActionQueue {
 }
 
 class CoreUpdate extends AbstractInteractableModule {
-  private actionQueue: ActionQueue = {
+  private readonly actionQueue: ActionQueue = {
     coreUpdateIsUpdateAvailable: {
       loadingMessage: 'Checking for possible regular or security update',
       finishMessage: undefined,
@@ -70,8 +70,8 @@ class CoreUpdate extends AbstractInteractableModule {
     },
   };
 
-  private selectorOutput: string = '.t3js-coreUpdate-output';
-  private updateButton: string = '.t3js-coreUpdate-button';
+  private readonly selectorOutput: string = '.t3js-coreUpdate-output';
+  private readonly updateButton: string = '.t3js-coreUpdate-button';
 
   /**
    * Clone of a DOM object acts as button template
diff --git a/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts b/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts
index 4ab46bdc4fbd..e911b601aa92 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/extension-compat-tester.ts
@@ -33,9 +33,9 @@ interface BrokenExtension {
  * Module: @typo3/install/module/extension-compat-tester
  */
 class ExtensionCompatTester extends AbstractInteractableModule {
-  private selectorCheckTrigger: string = '.t3js-extensionCompatTester-check';
-  private selectorUninstallTrigger: string = '.t3js-extensionCompatTester-uninstall';
-  private selectorOutputContainer: string = '.t3js-extensionCompatTester-output';
+  private readonly selectorCheckTrigger: string = '.t3js-extensionCompatTester-check';
+  private readonly selectorUninstallTrigger: string = '.t3js-extensionCompatTester-uninstall';
+  private readonly selectorOutputContainer: string = '.t3js-extensionCompatTester-output';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts
index 98ea6585dd35..3483e4dbe65f 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/extension-scanner.ts
@@ -49,11 +49,11 @@ interface RestFile {
 }
 
 class ExtensionScanner extends AbstractInteractableModule {
-  private listOfAffectedRestFileHashes: string[] = [];
-  private selectorExtensionContainer: string = '.t3js-extensionScanner-extension';
-  private selectorNumberOfFiles: string = '.t3js-extensionScanner-number-of-files';
-  private selectorScanSingleTrigger: string = '.t3js-extensionScanner-scan-single';
-  private selectorExtensionScanButton: string = '.t3js-extensionScanner-scan-all';
+  private readonly listOfAffectedRestFileHashes: string[] = [];
+  private readonly selectorExtensionContainer: string = '.t3js-extensionScanner-extension';
+  private readonly selectorNumberOfFiles: string = '.t3js-extensionScanner-number-of-files';
+  private readonly selectorScanSingleTrigger: string = '.t3js-extensionScanner-scan-single';
+  private readonly selectorExtensionScanButton: string = '.t3js-extensionScanner-scan-all';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts b/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts
index 1e20deeb857d..1d1ad5a7cee3 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/tca-ext-tables-check.ts
@@ -27,8 +27,8 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/tca-ext-tables-check
  */
 class TcaExtTablesCheck extends AbstractInteractableModule {
-  private selectorCheckTrigger: string = '.t3js-tcaExtTablesCheck-check';
-  private selectorOutputContainer: string = '.t3js-tcaExtTablesCheck-output';
+  private readonly selectorCheckTrigger: string = '.t3js-tcaExtTablesCheck-check';
+  private readonly selectorOutputContainer: string = '.t3js-tcaExtTablesCheck-output';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts b/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts
index c040871c8246..21dc16c97eed 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/tca-migrations-check.ts
@@ -27,8 +27,8 @@ import MessageInterface from '@typo3/install/message-interface';
  * Module: @typo3/install/module/tca-migrations-check
  */
 class TcaMigrationsCheck extends AbstractInteractableModule {
-  private selectorCheckTrigger: string = '.t3js-tcaMigrationsCheck-check';
-  private selectorOutputContainer: string = '.t3js-tcaMigrationsCheck-output';
+  private readonly selectorCheckTrigger: string = '.t3js-tcaMigrationsCheck-check';
+  private readonly selectorOutputContainer: string = '.t3js-tcaMigrationsCheck-output';
 
   public initialize(currentModal: JQuery): void {
     this.currentModal = currentModal;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/upgrade-docs.ts b/Build/Sources/TypeScript/install/module/upgrade/upgrade-docs.ts
index 65eccdbfd1e4..30a654f8238c 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/upgrade-docs.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/upgrade-docs.ts
@@ -27,11 +27,11 @@ import '@typo3/backend/element/icon-element';
  * Module: @typo3/install/module/upgrade-docs
  */
 class UpgradeDocs extends AbstractInteractableModule {
-  private selectorFulltextSearch: string = '.t3js-upgradeDocs-fulltext-search';
-  private selectorChosenField: string = '.t3js-upgradeDocs-chosen-select';
-  private selectorChangeLogsForVersionContainer: string = '.t3js-version-changes';
-  private selectorChangeLogsForVersion: string = '.t3js-changelog-list';
-  private selectorUpgradeDoc: string = '.t3js-upgrade-doc';
+  private readonly selectorFulltextSearch: string = '.t3js-upgradeDocs-fulltext-search';
+  private readonly selectorChosenField: string = '.t3js-upgradeDocs-chosen-select';
+  private readonly selectorChangeLogsForVersionContainer: string = '.t3js-version-changes';
+  private readonly selectorChangeLogsForVersion: string = '.t3js-changelog-list';
+  private readonly selectorUpgradeDoc: string = '.t3js-upgrade-doc';
 
   private chosenField: JQuery;
   private fulltextSearchField: JQuery;
diff --git a/Build/Sources/TypeScript/install/module/upgrade/upgrade-wizards.ts b/Build/Sources/TypeScript/install/module/upgrade/upgrade-wizards.ts
index 38bcc44153a2..2e83623a70bb 100644
--- a/Build/Sources/TypeScript/install/module/upgrade/upgrade-wizards.ts
+++ b/Build/Sources/TypeScript/install/module/upgrade/upgrade-wizards.ts
@@ -61,31 +61,31 @@ type UpgradeWizardDone = {
  * Module: @typo3/install/module/upgrade-wizards
  */
 class UpgradeWizards extends AbstractInteractableModule {
-  private selectorOutputWizardsContainer: string = '.t3js-upgradeWizards-wizards-output';
-  private selectorOutputDoneContainer: string = '.t3js-upgradeWizards-done-output';
-  private selectorWizardsBlockingAddsTemplate: string = '.t3js-upgradeWizards-blocking-adds-template';
-  private selectorWizardsBlockingAddsRows: string = '.t3js-upgradeWizards-blocking-adds-rows';
-  private selectorWizardsBlockingAddsExecute: string = '.t3js-upgradeWizards-blocking-adds-execute';
-  private selectorWizardsBlockingCharsetTemplate: string = '.t3js-upgradeWizards-blocking-charset-template';
-  private selectorWizardsBlockingCharsetFix: string = '.t3js-upgradeWizards-blocking-charset-fix';
-  private selectorWizardsDoneBodyTemplate: string = '.t3js-upgradeWizards-done-body-template';
-  private selectorWizardsDoneRows: string = '.t3js-upgradeWizards-done-rows';
-  private selectorWizardsDoneRowTemplate: string = '.t3js-upgradeWizards-done-row-template table tr';
-  private selectorWizardsDoneRowMarkUndone: string = '.t3js-upgradeWizards-done-markUndone';
-  private selectorWizardsDoneRowTitle: string = '.t3js-upgradeWizards-done-title';
-  private selectorWizardsListTemplate: string = '.t3js-upgradeWizards-list-template';
-  private selectorWizardsListRows: string = '.t3js-upgradeWizards-list-rows';
-  private selectorWizardsListRowTemplate: string = '.t3js-upgradeWizards-list-row-template';
-  private selectorWizardsListRowTitle: string = '.t3js-upgradeWizards-list-row-title';
-  private selectorWizardsListRowExplanation: string = '.t3js-upgradeWizards-list-row-explanation';
-  private selectorWizardsListRowExecute: string = '.t3js-upgradeWizards-list-row-execute';
-  private selectorWizardsInputTemplate: string = '.t3js-upgradeWizards-input';
-  private selectorWizardsInputTitle: string = '.t3js-upgradeWizards-input-title';
-  private selectorWizardsInputDescription: string = '.t3js-upgradeWizards-input-description';
-  private selectorWizardsInputHtml: string = '.t3js-upgradeWizards-input-html';
-  private selectorWizardsInputPerform: string = '.t3js-upgradeWizards-input-perform';
-  private selectorWizardsInputAbort: string = '.t3js-upgradeWizards-input-abort';
-  private securityUtility: SecurityUtility;
+  private readonly selectorOutputWizardsContainer: string = '.t3js-upgradeWizards-wizards-output';
+  private readonly selectorOutputDoneContainer: string = '.t3js-upgradeWizards-done-output';
+  private readonly selectorWizardsBlockingAddsTemplate: string = '.t3js-upgradeWizards-blocking-adds-template';
+  private readonly selectorWizardsBlockingAddsRows: string = '.t3js-upgradeWizards-blocking-adds-rows';
+  private readonly selectorWizardsBlockingAddsExecute: string = '.t3js-upgradeWizards-blocking-adds-execute';
+  private readonly selectorWizardsBlockingCharsetTemplate: string = '.t3js-upgradeWizards-blocking-charset-template';
+  private readonly selectorWizardsBlockingCharsetFix: string = '.t3js-upgradeWizards-blocking-charset-fix';
+  private readonly selectorWizardsDoneBodyTemplate: string = '.t3js-upgradeWizards-done-body-template';
+  private readonly selectorWizardsDoneRows: string = '.t3js-upgradeWizards-done-rows';
+  private readonly selectorWizardsDoneRowTemplate: string = '.t3js-upgradeWizards-done-row-template table tr';
+  private readonly selectorWizardsDoneRowMarkUndone: string = '.t3js-upgradeWizards-done-markUndone';
+  private readonly selectorWizardsDoneRowTitle: string = '.t3js-upgradeWizards-done-title';
+  private readonly selectorWizardsListTemplate: string = '.t3js-upgradeWizards-list-template';
+  private readonly selectorWizardsListRows: string = '.t3js-upgradeWizards-list-rows';
+  private readonly selectorWizardsListRowTemplate: string = '.t3js-upgradeWizards-list-row-template';
+  private readonly selectorWizardsListRowTitle: string = '.t3js-upgradeWizards-list-row-title';
+  private readonly selectorWizardsListRowExplanation: string = '.t3js-upgradeWizards-list-row-explanation';
+  private readonly selectorWizardsListRowExecute: string = '.t3js-upgradeWizards-list-row-execute';
+  private readonly selectorWizardsInputTemplate: string = '.t3js-upgradeWizards-input';
+  private readonly selectorWizardsInputTitle: string = '.t3js-upgradeWizards-input-title';
+  private readonly selectorWizardsInputDescription: string = '.t3js-upgradeWizards-input-description';
+  private readonly selectorWizardsInputHtml: string = '.t3js-upgradeWizards-input-html';
+  private readonly selectorWizardsInputPerform: string = '.t3js-upgradeWizards-input-perform';
+  private readonly selectorWizardsInputAbort: string = '.t3js-upgradeWizards-input-abort';
+  private readonly securityUtility: SecurityUtility;
 
   constructor() {
     super();
diff --git a/Build/Sources/TypeScript/install/renderable/flash-message.ts b/Build/Sources/TypeScript/install/renderable/flash-message.ts
index d4f206cb166b..7b3c93c7ba7f 100644
--- a/Build/Sources/TypeScript/install/renderable/flash-message.ts
+++ b/Build/Sources/TypeScript/install/renderable/flash-message.ts
@@ -18,7 +18,7 @@ import Severity from './severity';
  * Module: @typo3/install/module/flash-message
  */
 class FlashMessage {
-  private template: JQuery = $('<div class="t3js-message typo3-message alert"><h4></h4><p class="messageText"></p></div>');
+  private readonly template: JQuery = $('<div class="t3js-message typo3-message alert"><h4></h4><p class="messageText"></p></div>');
 
   public render(severity: number, title: string, message?: string): JQuery {
     const flashMessage = this.template.clone();
diff --git a/Build/Sources/TypeScript/install/renderable/info-box.ts b/Build/Sources/TypeScript/install/renderable/info-box.ts
index d57c87236106..281dadc31f8c 100644
--- a/Build/Sources/TypeScript/install/renderable/info-box.ts
+++ b/Build/Sources/TypeScript/install/renderable/info-box.ts
@@ -18,7 +18,7 @@ import Severity from './severity';
  * Module: @typo3/install/module/info-box
  */
 class InfoBox {
-  private template: JQuery = $(
+  private readonly template: JQuery = $(
     '<div class="t3js-infobox callout callout-sm">' +
       '<h4 class="callout-title"></h4>' +
       '<div class="callout-body"></div>' +
diff --git a/Build/Sources/TypeScript/install/renderable/progress-bar.ts b/Build/Sources/TypeScript/install/renderable/progress-bar.ts
index ab43f1edb9ac..61e0ce8bc756 100644
--- a/Build/Sources/TypeScript/install/renderable/progress-bar.ts
+++ b/Build/Sources/TypeScript/install/renderable/progress-bar.ts
@@ -18,7 +18,7 @@ import Severity from './severity';
  * Module: @typo3/install/module/progress-bar
  */
 class ProgressBar {
-  private template: JQuery = $(
+  private readonly template: JQuery = $(
     '<div class="progress">' +
       '<div class="t3js-progressbar progress-bar progress-bar-striped progress-bar-animated" role="progressbar" aria-valuenow="100" ' +
         'aria-valuemin="0" aria-valuemax="100" style="width: 100%"> <span></span>' +
diff --git a/Build/Sources/TypeScript/install/router.ts b/Build/Sources/TypeScript/install/router.ts
index ee58c9ce321c..a88a6551e6d9 100644
--- a/Build/Sources/TypeScript/install/router.ts
+++ b/Build/Sources/TypeScript/install/router.ts
@@ -26,12 +26,12 @@ import '@typo3/backend/element/spinner-element';
 import MessageInterface from '@typo3/install/message-interface';
 
 class Router {
-  private rootSelector: string = '.t3js-body';
-  private contentSelector: string = '.t3js-module-body';
+  private readonly rootSelector: string = '.t3js-body';
+  private readonly contentSelector: string = '.t3js-module-body';
 
-  private scaffoldSelector: string = '.t3js-scaffold';
-  private scaffoldContentOverlaySelector: string = '.t3js-scaffold-content-overlay';
-  private scaffoldMenuToggleSelector: string = '.t3js-topbar-button-modulemenu';
+  private readonly scaffoldSelector: string = '.t3js-scaffold';
+  private readonly scaffoldContentOverlaySelector: string = '.t3js-scaffold-content-overlay';
+  private readonly scaffoldMenuToggleSelector: string = '.t3js-topbar-button-modulemenu';
 
   private rootContainer: HTMLElement;
   private controller: string;
diff --git a/Build/Sources/TypeScript/lowlevel/query-generator.ts b/Build/Sources/TypeScript/lowlevel/query-generator.ts
index 5d77b0c1069a..1d307914e9cb 100644
--- a/Build/Sources/TypeScript/lowlevel/query-generator.ts
+++ b/Build/Sources/TypeScript/lowlevel/query-generator.ts
@@ -20,8 +20,8 @@ import RegularEvent from '@typo3/core/event/regular-event';
  * This module handle the QueryGenerator forms.
  */
 class QueryGenerator {
-  private form: HTMLFormElement = null;
-  private limitField: HTMLInputElement = null;
+  private readonly form: HTMLFormElement = null;
+  private readonly limitField: HTMLInputElement = null;
 
   constructor() {
     this.form = document.querySelector('form[name="queryform"]');
diff --git a/Build/Sources/TypeScript/opendocs/toolbar/opendocs-menu.ts b/Build/Sources/TypeScript/opendocs/toolbar/opendocs-menu.ts
index 441ae538f349..1e21ef5f4e04 100644
--- a/Build/Sources/TypeScript/opendocs/toolbar/opendocs-menu.ts
+++ b/Build/Sources/TypeScript/opendocs/toolbar/opendocs-menu.ts
@@ -111,7 +111,7 @@ class OpendocsMenu {
   /**
    * closes the menu (e.g. when clicked on an item)
    */
-  private toggleMenu = (): void => {
+  private readonly toggleMenu = (): void => {
     $('.scaffold').removeClass('scaffold-toolbar-expanded');
     $(Selectors.containerSelector).toggleClass('open');
   };
diff --git a/Build/Sources/TypeScript/recycler/recycler.ts b/Build/Sources/TypeScript/recycler/recycler.ts
index 82eee62014a3..09587d5df120 100644
--- a/Build/Sources/TypeScript/recycler/recycler.ts
+++ b/Build/Sources/TypeScript/recycler/recycler.ts
@@ -217,7 +217,7 @@ class Recycler {
   /**
    * Handles the clicks on checkboxes in the records table
    */
-  private handleCheckboxStateChanged = (e: Event): void => {
+  private readonly handleCheckboxStateChanged = (e: Event): void => {
     const $checkbox = $(e.target);
     const $tr = $checkbox.parents('tr');
     const table = $tr.data('table');
@@ -315,7 +315,7 @@ class Recycler {
     }).finally(() => NProgress.done());
   }
 
-  private deleteRecord = (e: Event): void => {
+  private readonly deleteRecord = (e: Event): void => {
     if (TYPO3.settings.Recycler.deleteDisable) {
       return;
     }
@@ -360,7 +360,7 @@ class Recycler {
     });
   };
 
-  private undoRecord = (e: Event): void => {
+  private readonly undoRecord = (e: Event): void => {
     const $tr = $(e.target).parents('tr');
     const isMassUndo = $tr.parent().prop('tagName') !== 'TBODY'; // undoRecord() was invoked by the mass delete button
 
diff --git a/Build/Sources/TypeScript/workspaces/backend.ts b/Build/Sources/TypeScript/workspaces/backend.ts
index 596cac7333be..a23e53905c17 100644
--- a/Build/Sources/TypeScript/workspaces/backend.ts
+++ b/Build/Sources/TypeScript/workspaces/backend.ts
@@ -65,8 +65,8 @@ type History = {
  * workspace preview. Contains all JavaScript of the main BE module.
  */
 class Backend extends Workspaces {
-  private elements: { [key: string]: JQuery } = {};
-  private settings: { [key: string]: string | number } = {
+  private readonly elements: { [key: string]: JQuery } = {};
+  private readonly settings: { [key: string]: string | number } = {
     dir: 'ASC',
     id: TYPO3.settings.Workspaces.id,
     depth: 1,
@@ -77,14 +77,14 @@ class Backend extends Workspaces {
     start: 0,
     filterTxt: '',
   };
-  private paging: Record<string, number> = {
+  private readonly paging: Record<string, number> = {
     currentPage: 1,
     totalPages: 1,
     totalItems: 0,
   };
   private latestPath: string = '';
   private markedRecordsForMassAction: string[] = [];
-  private indentationPadding: number = 26;
+  private readonly indentationPadding: number = 26;
 
   constructor() {
     super();
@@ -500,7 +500,7 @@ class Backend extends Workspaces {
     });
   }
 
-  private handleCheckboxStateChanged = (e: Event): void => {
+  private readonly handleCheckboxStateChanged = (e: Event): void => {
     const $checkbox = $(e.target);
     const $tr = $checkbox.parents('tr');
     const checked = $checkbox.prop('checked');
@@ -799,7 +799,7 @@ class Backend extends Workspaces {
    *
    * @param {Event} e
    */
-  private viewChanges = (e: JQueryEventObject): void => {
+  private readonly viewChanges = (e: JQueryEventObject): void => {
     e.preventDefault();
 
     const $tr = $(e.currentTarget).closest('tr');
@@ -972,7 +972,7 @@ class Backend extends Workspaces {
    *
    * @param {Event} e
    */
-  private confirmDeleteRecordFromWorkspace = (e: JQueryEventObject): void => {
+  private readonly confirmDeleteRecordFromWorkspace = (e: JQueryEventObject): void => {
     const $tr = $(e.target).closest('tr');
     const modal = Modal.confirm(
       TYPO3.lang['window.discard.title'],
@@ -1014,7 +1014,7 @@ class Backend extends Workspaces {
   /**
    * Runs a mass action
    */
-  private runSelectionAction = (e: JQueryEventObject): void => {
+  private readonly runSelectionAction = (e: JQueryEventObject): void => {
     const selectedAction = $(e.currentTarget).val();
     const integrityCheckRequired = selectedAction !== 'discard';
 
@@ -1055,7 +1055,7 @@ class Backend extends Workspaces {
   /**
    * Adds a slide to the wizard concerning an integrity check warning.
    */
-  private addIntegrityCheckWarningToWizard = (): void => {
+  private readonly addIntegrityCheckWarningToWizard = (): void => {
     Wizard.addSlide(
       'integrity-warning',
       'Warning',
@@ -1103,7 +1103,7 @@ class Backend extends Workspaces {
   /**
    * Runs a mass action
    */
-  private runMassAction = (e: JQueryEventObject): void => {
+  private readonly runMassAction = (e: JQueryEventObject): void => {
     const selectedAction = $(e.currentTarget).val();
     const integrityCheckRequired = selectedAction !== 'discard';
 
@@ -1198,7 +1198,7 @@ class Backend extends Workspaces {
    *
    * @param {Event} e
    */
-  private sendToSpecificStageAction = (e: JQueryEventObject): void => {
+  private readonly sendToSpecificStageAction = (e: JQueryEventObject): void => {
     const affectedRecords: Array<{ [key: string]: number | string }> = [];
     const stage = $(e.currentTarget).val();
     for (let i = 0; i < this.markedRecordsForMassAction.length; ++i) {
@@ -1262,7 +1262,7 @@ class Backend extends Workspaces {
   /**
    * Fetches and renders available preview links
    */
-  private generatePreviewLinks = (): void => {
+  private readonly generatePreviewLinks = (): void => {
     this.sendRemoteRequest(
       this.generateRemoteActionsPayload('generateWorkspacePreviewLinksForAllLanguages', [
         this.settings.id,
diff --git a/Build/Sources/TypeScript/workspaces/preview.ts b/Build/Sources/TypeScript/workspaces/preview.ts
index 95b4f47aa49d..e7f3963c62ed 100644
--- a/Build/Sources/TypeScript/workspaces/preview.ts
+++ b/Build/Sources/TypeScript/workspaces/preview.ts
@@ -40,7 +40,7 @@ enum Identifiers {
  */
 class Preview extends Workspaces {
   private currentSlidePosition: number = 100;
-  private elements: { [key: string]: JQuery } = {};
+  private readonly elements: { [key: string]: JQuery } = {};
 
   constructor() {
     super();
@@ -114,7 +114,7 @@ class Preview extends Workspaces {
    *
    * @param {Event} e
    */
-  private updateSlidePosition = (e: Event): void => {
+  private readonly updateSlidePosition = (e: Event): void => {
     this.currentSlidePosition = parseInt((e.target as HTMLInputElement).value, 10);
     this.resizeViews();
   };
@@ -138,7 +138,7 @@ class Preview extends Workspaces {
   /**
    * Renders the discard window
    */
-  private renderDiscardWindow = (): void => {
+  private readonly renderDiscardWindow = (): void => {
     const modal = Modal.confirm(
       TYPO3.lang['window.discardAll.title'],
       TYPO3.lang['window.discardAll.message'],
@@ -178,7 +178,7 @@ class Preview extends Workspaces {
   /**
    * Renders the "send page to stage" window
    */
-  private renderSendPageToStageWindow = (e: JQueryEventObject): void => {
+  private readonly renderSendPageToStageWindow = (e: JQueryEventObject): void => {
     const me = (<HTMLElement>e.currentTarget);
     const direction = me.dataset.direction;
     let actionName;
@@ -222,7 +222,7 @@ class Preview extends Workspaces {
    *
    * @param {Event} e
    */
-  private changePreviewMode = (e: JQueryEventObject): void => {
+  private readonly changePreviewMode = (e: JQueryEventObject): void => {
     e.preventDefault();
 
     const $trigger = $(e.currentTarget);
-- 
GitLab