From d0c631194c37ae311f84a672ad54b0ffa27c832b Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sun, 20 Sep 2026 11:14:31 +0200 Subject: [PATCH] fix(multiple): replace hasOwnProperty with Object.hasOwn Replaces all the usages of `hasOwnProperty` with `Object.hasOwn` since the latter handles some edge cases better. We went through this exercise on the framework repo some time ago. --- docs/tools/lighthouse-audit.mjs | 4 ++-- .../behaviors/event-manager/keyboard-event-manager.ts | 2 +- src/bazel-tsconfig-build.json | 2 +- src/cdk/drag-drop/dom/styling.ts | 2 +- .../position/flexible-connected-position-strategy.ts | 6 ++---- src/components-examples/example-data.ts | 2 +- src/material/tabs/tab.ts | 2 +- tools/dgeni/common/decorators.ts | 2 +- tools/dgeni/tsconfig.json | 2 +- tools/tsconfig.json | 2 +- tools/tslint-rules/lifecycleHookInterfaceRule.ts | 2 +- tsconfig.json | 2 +- tslint.json | 1 + 13 files changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/tools/lighthouse-audit.mjs b/docs/tools/lighthouse-audit.mjs index 4a48e58d3833..02fdc1dbd48d 100644 --- a/docs/tools/lighthouse-audit.mjs +++ b/docs/tools/lighthouse-audit.mjs @@ -229,9 +229,9 @@ function parseMinScores(raw) { .map(x => x.split(':')) .forEach(([key, val]) => (minScores[key] = Number(val) / 100)); - if (minScores.hasOwnProperty('all')) { + if (Object.hasOwn(minScores, 'all')) { AUDIT_CATEGORIES.forEach( - cat => minScores.hasOwnProperty(cat) || (minScores[cat] = minScores.all), + cat => Object.hasOwn(minScores, cat) || (minScores[cat] = minScores.all), ); delete minScores.all; } diff --git a/src/aria/private/behaviors/event-manager/keyboard-event-manager.ts b/src/aria/private/behaviors/event-manager/keyboard-event-manager.ts index 0b41a08c8f8d..8b3bbcacd507 100644 --- a/src/aria/private/behaviors/event-manager/keyboard-event-manager.ts +++ b/src/aria/private/behaviors/event-manager/keyboard-event-manager.ts @@ -60,7 +60,7 @@ export class KeyboardEventManager extends EventManager< } private _normalizeInputs(...args: unknown[]) { - const withModifiers = Array.isArray(args[0]) || Modifier.hasOwnProperty(args[0] as string); + const withModifiers = Array.isArray(args[0]) || Object.hasOwn(Modifier, args[0] as string); const modifiers = withModifiers ? args[0] : Modifier.None; const key = withModifiers ? args[1] : args[0]; const handler = withModifiers ? args[2] : args[1]; diff --git a/src/bazel-tsconfig-build.json b/src/bazel-tsconfig-build.json index 2b39e1c95f43..5ffd05dc29b5 100644 --- a/src/bazel-tsconfig-build.json +++ b/src/bazel-tsconfig-build.json @@ -31,7 +31,7 @@ "sourceMap": true, "inlineSources": true, "target": "es2022", - "lib": ["es2020", "dom"], + "lib": ["es2022", "dom"], "types": [], "skipLibCheck": true, "paths": { diff --git a/src/cdk/drag-drop/dom/styling.ts b/src/cdk/drag-drop/dom/styling.ts index 429936438096..357d90388ea8 100644 --- a/src/cdk/drag-drop/dom/styling.ts +++ b/src/cdk/drag-drop/dom/styling.ts @@ -27,7 +27,7 @@ export function extendStyles( importantProperties?: Set, ) { for (let key in source) { - if (source.hasOwnProperty(key)) { + if (Object.hasOwn(source, key)) { const value = source[key]; if (value) { diff --git a/src/cdk/overlay/position/flexible-connected-position-strategy.ts b/src/cdk/overlay/position/flexible-connected-position-strategy.ts index 897e205915dc..dfadadb9c915 100644 --- a/src/cdk/overlay/position/flexible-connected-position-strategy.ts +++ b/src/cdk/overlay/position/flexible-connected-position-strategy.ts @@ -65,9 +65,7 @@ export function createFlexibleConnectedPositionStrategy( /** Supported locations in the DOM for connected overlays. */ export type FlexibleOverlayPopoverLocation = - | 'global' - | 'inline' - | {type: 'parent'; element: Element}; + 'global' | 'inline' | {type: 'parent'; element: Element}; /** * A strategy for positioning overlays. Using this strategy, an overlay is given an @@ -1390,7 +1388,7 @@ function extendStyles( source: CSSStyleDeclaration, ): CSSStyleDeclaration { for (let key in source) { - if (source.hasOwnProperty(key)) { + if (Object.hasOwn(source, key)) { destination[key] = source[key]; } } diff --git a/src/components-examples/example-data.ts b/src/components-examples/example-data.ts index e7af3263cc1a..5bbe10655964 100644 --- a/src/components-examples/example-data.ts +++ b/src/components-examples/example-data.ts @@ -23,7 +23,7 @@ export class ExampleData { componentNames!: string[]; constructor(example: string) { - if (!example || !EXAMPLE_COMPONENTS.hasOwnProperty(example)) { + if (!example || !Object.hasOwn(EXAMPLE_COMPONENTS, example)) { return; } diff --git a/src/material/tabs/tab.ts b/src/material/tabs/tab.ts index 2d59fd953c12..592cd278a8f8 100644 --- a/src/material/tabs/tab.ts +++ b/src/material/tabs/tab.ts @@ -142,7 +142,7 @@ export class MatTab implements OnInit, OnChanges, OnDestroy { } ngOnChanges(changes: SimpleChanges): void { - if (changes.hasOwnProperty('textLabel') || changes.hasOwnProperty('disabled')) { + if (Object.hasOwn(changes, 'textLabel') || Object.hasOwn(changes, 'disabled')) { this._stateChanges.next(); } } diff --git a/tools/dgeni/common/decorators.ts b/tools/dgeni/common/decorators.ts index 1dceb804717c..52ada3ebcc69 100644 --- a/tools/dgeni/common/decorators.ts +++ b/tools/dgeni/common/decorators.ts @@ -6,7 +6,7 @@ import {CategorizedClassDoc, DeprecationInfo, HasDecoratorsDoc} from './dgeni-de import {findJsDocTag, hasJsDocTag} from './tags'; export function isMethod(doc: MemberDoc): boolean { - return doc.hasOwnProperty('parameters') && !doc.isGetAccessor && !doc.isSetAccessor; + return Object.hasOwn(doc, 'parameters') && !doc.isGetAccessor && !doc.isSetAccessor; } export function isGenericTypeParameter(doc: MemberDoc): boolean { diff --git a/tools/dgeni/tsconfig.json b/tools/dgeni/tsconfig.json index 4edbcdca5beb..ec0cb2e2c481 100644 --- a/tools/dgeni/tsconfig.json +++ b/tools/dgeni/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "noUnusedParameters": false, "noUnusedLocals": false, - "lib": ["es2020", "dom"], + "lib": ["es2022", "dom"], "moduleResolution": "node", "esModuleInterop": true, "strictNullChecks": true, diff --git a/tools/tsconfig.json b/tools/tsconfig.json index c77c2883f0f0..9660ddac5297 100644 --- a/tools/tsconfig.json +++ b/tools/tsconfig.json @@ -7,7 +7,7 @@ "sourceMap": true, "declaration": true, "esModuleInterop": true, - "lib": ["es2020"], + "lib": ["es2022"], "skipLibCheck": true, "types": ["node"] }, diff --git a/tools/tslint-rules/lifecycleHookInterfaceRule.ts b/tools/tslint-rules/lifecycleHookInterfaceRule.ts index b446076f29d7..d5c29b3a47bc 100644 --- a/tools/tslint-rules/lifecycleHookInterfaceRule.ts +++ b/tools/tslint-rules/lifecycleHookInterfaceRule.ts @@ -28,7 +28,7 @@ class Walker extends Lint.RuleWalker { if ( !ts.isMethodDeclaration(member) || !ts.isIdentifier(member.name) || - !HOOKS_TO_INTERFACES.hasOwnProperty(member.name.text) + !Object.hasOwn(HOOKS_TO_INTERFACES, member.name.text) ) { continue; } diff --git a/tsconfig.json b/tsconfig.json index 7c91076e0a64..fd474cdb9418 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -24,7 +24,7 @@ "skipLibCheck": true, "strictBindCallApply": true, "target": "es2022", - "lib": ["es2020", "dom"], + "lib": ["es2022", "dom"], "types": ["jasmine"], "paths": { "@angular/aria": ["./src/aria"], diff --git a/tslint.json b/tslint.json index 6bb013e2abde..3ef24bc0c784 100644 --- a/tslint.json +++ b/tslint.json @@ -42,6 +42,7 @@ {"name": ["*", "removeChild"], "message": "Use `remove` instead instead."}, {"name": ["CommonModule"], "message": "Import the necessary symbols directly instead."}, {"name": ["*", "compileComponents"], "message": "`compileComponents` is not necessary."}, + {"name": ["*", "hasOwnProperty"], "message": "Use `Object.hasOwn` instead."}, { "name": ["isDevMode"], "message": "Use `typeof ngDevMode === 'undefined' || ngDevMode` instead"