Replace unsafe/legacy types in ui-kit utilities, directives, layout, and misc small areas - #702
Open
fpigeonjr wants to merge 6 commits into
Conversation
This was referenced Sep 3, 2026
There was a problem hiding this comment.
🟡 Changes recommended
Public typing regressions, strict-null incompatibility, and stacked out-of-scope changes must be resolved before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Replaces unsafe TypeScript types across the Angular library, while also incorporating stacked lint autofixes and datepicker behavior fixes.
Changes:
- Adds stronger public API, event, model, and lifecycle typings.
- Fixes datepicker outside-click behavior with unit and browser tests.
- Modernizes lint/RxJS patterns and lowers the warning baseline.
File summaries
| File | Description |
|---|---|
test-app/src/typings.d.ts |
Modernizes ambient declaration |
test-app/src/app/datepicker-gallery/datepicker-gallery.component.ts |
Adds datepicker gallery |
test-app/src/app/datepicker-gallery/datepicker-gallery.component.spec.ts |
Tests gallery creation |
test-app/src/app/datepicker-gallery/datepicker-gallery.component.html |
Adds datepicker harness |
test-app/src/app/app.module.ts |
Registers gallery route |
test-app/e2e/datepicker.spec.ts |
Adds browser regression tests |
src/ui-kit/wrappers/label-wrapper/label-wrapper.spec.ts |
Types test fixture |
src/ui-kit/wrappers/label-wrapper/label-wrapper.component.ts |
Declares lifecycle interfaces |
src/ui-kit/wrappers/fieldset-wrapper/fieldset-wrapper.spec.ts |
Types fixture and changes |
src/ui-kit/wrappers/fieldset-wrapper/fieldset-wrapper.component.ts |
Strengthens wrapper types |
src/ui-kit/utilities/key-helper/key-helper.ts |
Adds typed event abstraction |
src/ui-kit/utilities/key-helper/key-helper.spec.ts |
Applies const cleanup |
src/ui-kit/utilities/deprecator/deprecator.ts |
Replaces unsafe object types |
src/ui-kit/utilities/are-equal/are-equal.ts |
Accepts unknown values safely |
src/ui-kit/typings.d.ts |
Types JSON as unknown |
src/ui-kit/types.ts |
Strengthens shared models |
src/ui-kit/type-check-helpers.ts |
Accepts unknown inputs |
src/ui-kit/pipes/filesize/filesize.pipe.spec.ts |
Applies const cleanup |
src/ui-kit/pipes/date-time-display/date-time-display.pipe.ts |
Types pipe contract |
src/ui-kit/layout/toolbar/toolbar.spec.ts |
Types test fixture |
src/ui-kit/layout/toolbar/toolbar.component.ts |
Types action output |
src/ui-kit/layout/toolbar/aside-toggle.spec.ts |
Types fixtures |
src/ui-kit/layout/toolbar/aside-toggle.component.ts |
Declares lifecycle interfaces |
src/ui-kit/layout/pagination/pagination.component.ts |
Types pagination options |
src/ui-kit/layout/pagination/pagination.component.spec.ts |
Applies const cleanup |
src/ui-kit/layout/header/header.component.ts |
Applies const cleanup |
src/ui-kit/layout/header/header.component.spec.ts |
Applies const cleanup |
src/ui-kit/layout/filters-wrapper/filters-wrapper.component.ts |
Types report subjects |
src/ui-kit/layout/filter-drawer/filter-drawer.component.ts |
Types clear output |
src/ui-kit/layout/filter-drawer/filter-drawer-item/filter-drawer-item.component.ts |
Types filter removal |
src/ui-kit/layout/filter-drawer/filter-drawer-chip/filter-drawer-chip.component.ts |
Types chip output |
src/ui-kit/layout/filter-drawer/dynamic-chips/dynamic-chips.directive.ts |
Adds filter model types |
src/ui-kit/layout-deprecated/page.spec.ts |
Applies const cleanup |
src/ui-kit/layout-deprecated/list-results-message.spec.ts |
Applies const cleanup |
src/ui-kit/layout-deprecated/grid/row.spec.ts |
Applies const cleanup |
src/ui-kit/layout-deprecated/grid/grid.spec.ts |
Applies const cleanup |
src/ui-kit/layout-deprecated/grid/column.spec.ts |
Applies const cleanup |
src/ui-kit/layout-deprecated/grid/column.directive.ts |
Applies const cleanup |
src/ui-kit/form-templates/phone-entry/phone-entry.component.ts |
Declares lifecycle interface |
src/ui-kit/form-templates/international-phone/sam-international-prefix/international-prefix.component.ts |
Declares initialization lifecycle |
src/ui-kit/form-templates/international-phone/sam-extension/extension.component.ts |
Declares initialization lifecycle |
src/ui-kit/form-service.ts |
Replaces wrapper object type |
src/ui-kit/form-controls/upload-v2/upload-v2.component.ts |
Declares lifecycle interfaces |
src/ui-kit/form-controls/toggle-switch/toggle-switch.component.ts |
Applies const cleanup |
src/ui-kit/form-controls/textarea/textarea.component.ts |
Adds lifecycle typing |
src/ui-kit/form-controls/select/select.component.ts |
Adds initialization lifecycle |
src/ui-kit/form-controls/sam-sds-autocomplete/selected-result/selected-result.component.ts |
Replaces legacy object type |
src/ui-kit/form-controls/sam-sds-autocomplete/selected-result/selected-result.component.spec.ts |
Applies const cleanup |
src/ui-kit/form-controls/sam-sds-autocomplete/selected-result/models/sds-selected-item-model-helper.ts |
Applies const cleanup |
src/ui-kit/form-controls/sam-sds-autocomplete/autocomplete/autocomplete.component.spec.ts |
Applies const cleanup |
src/ui-kit/form-controls/sam-sds-autocomplete/autocomplete-search/autocomplete-search.component.ts |
Modernizes local declarations |
src/ui-kit/form-controls/sam-sds-autocomplete/autocomplete-search/autocomplete-search.component.spec.ts |
Applies const cleanup |
src/ui-kit/form-controls/sam-sds-autocomplete/autocomplete-search/autocomplete-seach-test-service.spec.ts |
Modernizes test service types |
src/ui-kit/form-controls/radiobutton/radiobutton.component.ts |
Declares lifecycle interfaces |
src/ui-kit/form-controls/number/number.component.ts |
Declares lifecycle interfaces |
src/ui-kit/form-controls/date/date.component.ts |
Adds lifecycle and consts |
src/ui-kit/form-controls/checkbox/checkbox.component.ts |
Declares initialization lifecycle |
src/ui-kit/form-controls/autocomplete/autocomplete.component.ts |
Adds lifecycle and consts |
src/ui-kit/form-controls/autocomplete-multiselect/autocomplete-multiselect.component.ts |
Adds lifecycle and consts |
src/ui-kit/filters/filters.component.ts |
Types filter model |
src/ui-kit/experimental/video-player/video-player.component.ts |
Declares lifecycle interfaces |
src/ui-kit/experimental/title/title.component.ts |
Applies const cleanup |
src/ui-kit/experimental/tabs/tab-nav-bar/tab-nav-bar.ts |
Declares lifecycle interface |
src/ui-kit/experimental/tabs/tab-group.ts |
Adds lifecycle and const |
src/ui-kit/experimental/tabs/tab-body.ts |
Removes redundant aliases |
src/ui-kit/experimental/sideNavigationToolbar/sideNavigationToolbar/sideNavigationToolbar.component.ts |
Declares lifecycle interface |
src/ui-kit/experimental/search/search.service.ts |
Applies const cleanup |
src/ui-kit/experimental/search/search.component.ts |
Adds lifecycle and const |
src/ui-kit/experimental/patterns/layout/components/title-section.component.ts |
Keeps host ID synchronized |
src/ui-kit/experimental/patterns/layout/components/sidenav/sidenav.ts |
Modernizes RxJS usage |
src/ui-kit/experimental/patterns/layout/components/sidenav/sidenav.spec.ts |
Tests dynamic sidenavs |
src/ui-kit/experimental/patterns/layout/components/page/page.component.ts |
Declares lifecycle interfaces |
src/ui-kit/experimental/patterns/layout/components/actionbar.component.ts |
Declares lifecycle interface |
src/ui-kit/experimental/listbox/listbox.component.ts |
Fixes announced label |
src/ui-kit/experimental/layout/layout.component.ts |
Declares initialization lifecycle |
src/ui-kit/experimental/hierarchical/selected-result/selected-result.component.spec.ts |
Applies const cleanup |
src/ui-kit/experimental/hierarchical/models/SamHierarchicalTreeHeaderConfiguration.ts |
Replaces wrapper string |
src/ui-kit/experimental/hierarchical/models/SamHierarchicalTreeConfiguration.ts |
Replaces wrapper string |
src/ui-kit/experimental/hierarchical/models/SamHierarchicalConfiguration.ts |
Replaces wrapper string |
src/ui-kit/experimental/hierarchical/hierarchical-tree/hierarchical-tree.component.ts |
Replaces legacy object types |
src/ui-kit/experimental/hierarchical/hierarchical-tree/hierarchical-tree.component.spec.ts |
Applies const cleanup |
src/ui-kit/experimental/hierarchical/hierarchical-tree-selectedItem.model.ts |
Applies const cleanup |
src/ui-kit/experimental/hierarchical/hierarchical-tree-header/hierarchical-tree-header.component.spec.ts |
Applies const cleanup |
src/ui-kit/experimental/hierarchical/hierarchical-tree-grid/hierarchical-tree-grid.component.ts |
Adds lifecycle and consts |
src/ui-kit/experimental/hierarchical/hierarchical-tree-grid/hierarchical-tree-grid.component.spec.ts |
Applies const cleanup |
src/ui-kit/experimental/hierarchical/hierarchical-test-service.spec.ts |
Modernizes test service types |
src/ui-kit/experimental/hierarchical/autocomplete/autocomplete.component.ts |
Replaces legacy declarations |
src/ui-kit/experimental/dollar/dollar.component.ts |
Declares lifecycle interfaces |
src/ui-kit/experimental/date-range-v2/datepicker/picker.spec.ts |
Enables click regression tests |
src/ui-kit/experimental/date-range-v2/datepicker/picker.component.ts |
Fixes popup click handling |
src/ui-kit/experimental/date-range-v2/datepicker/calendar.spec.ts |
Applies const cleanup |
src/ui-kit/experimental/button-next/button.component.ts |
Replaces wrapper string |
src/ui-kit/experimental/aria/utils/events.ts |
Replaces wrapper object |
src/ui-kit/experimental/aria/abstract-grid/abstract-grid.ts |
Replaces wrapper object |
src/ui-kit/experimental/aria/abstract-grid/abstract-cell.ts |
Replaces wrapper object |
src/ui-kit/experimental/aria/abstract-combobox/abstract-combobox.ts |
Replaces wrapper object |
src/ui-kit/experimental/alert/alert.component.ts |
Declares initialization lifecycle |
src/ui-kit/experimental/actions-list/actions-list.component.ts |
Adds lifecycle and consts |
src/ui-kit/elements/button/button.spec.ts |
Types fixture and events |
src/ui-kit/elements/button/button.component.ts |
Types button API |
src/ui-kit/directives/tab-outside/taboutside.spec.ts |
Types fixture and output |
src/ui-kit/directives/tab-outside/taboutside.directive.ts |
Types focus output |
src/ui-kit/directives/sticky/sticky.spec.ts |
Types fixture and mocks |
src/ui-kit/directives/sticky/sticky.component.ts |
Adds DOM-specific types |
src/ui-kit/directives/focus/focus.spec.ts |
Types fixture and output |
src/ui-kit/directives/external-link/external-link.spec.ts |
Applies const cleanup |
src/ui-kit/directives/drag-drop/drag-drop.spec.ts |
Types test fixture |
src/ui-kit/directives/click-outside/click-outside.spec.ts |
Types fixture and output |
src/ui-kit/components/tabs/tabs.component.ts |
Declares changes lifecycle |
src/ui-kit/components/sidenav/sidenav/sidenav.component.ts |
Declares changes lifecycle |
src/ui-kit/components/sidenav/menu-item/menu-item.spec.ts |
Applies const cleanup |
src/ui-kit/components/pagination/pagination.spec.ts |
Applies const cleanup |
src/ui-kit/components/pagination/pagination.component.ts |
Replaces var declarations |
src/ui-kit/components/page-title/page-title.component.ts |
Removes redundant alias |
src/ui-kit/components/modal/modal.component.ts |
Adds lifecycle and consts |
src/ui-kit/components/data-table/sort-header.component.ts |
Removes redundant alias |
src/ui-kit/components/data-table/data-table.component.ts |
Declares changes lifecycle |
src/ui-kit/components/comments/comments.spec.ts |
Applies const cleanup |
src/ui-kit/components/comments/comments.component.ts |
Declares destruction lifecycle |
src/ui-kit/components/alert/alert.component.ts |
Declares initialization lifecycle |
src/ui-kit/components/alert-footer/alert-footer.component.ts |
Declares initialization lifecycle |
src/ui-kit/components/actions/actions-dropdown/actions-dropdown.spec.ts |
Applies const cleanup |
src/formly/sam-formly.ts |
Adds generic template contract |
src/formly/components/autocomplete/test.service.ts |
Types observable result |
eslint.config.mjs |
Adds RxJS misuse guard |
eslint-baseline.json |
Lowers warning ceilings |
Review details
- Files reviewed: 124/126 changed files
- Comments generated: 7
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
fpigeonjr
changed the base branch from
master
to
gh-582-apply-safe-eslint-autofixes-and-lower-the-baseline
September 3, 2026 18:29
fpigeonjr
force-pushed
the
gh-586-replace-unsafe-and-legacy-typescript-types
branch
from
September 3, 2026 18:33
c669a84 to
bb6a7ff
Compare
- are-equal.ts: any -> unknown, precise internal helper types - deprecator.ts: any -> object for parentClass/render, typed record cast for dynamic property access - key-helper.ts: introduce KeyEventLike to model the cross-browser event shapes this helper reads (including legacy keyIdentifier/numeric key fixtures), replacing all any/Function usages; preserves the original tolerant behavior for malformed event input via toKeyEventLike Lowers the root ESLint warning baseline 1307 -> 1289.
- taboutside.directive.ts: EventEmitter<any> -> EventEmitter<void>,
typed hasFocusChanged(target: EventTarget)
- sticky.component.ts: typed resize/scroll(event: Event), replaced any
casts on getElementsByClassName results with
HTMLCollectionOf<HTMLElement>, introduced exported OffsetParentLike
interface for getElemDistanceToTop's recursive offsetParent walk
- click-outside/focus/tab-outside/drag-drop/sticky specs: replaced
EventEmitter<any>/fixture: any with concrete
EventEmitter<boolean>/ComponentFixture<TestComponent> types, and
Event() instances instead of {}/undefined for resize/scroll calls
Lowers the root ESLint warning baseline 1289 -> 1274.
- dynamic-chips.directive.ts: typed `map` input, `remove` emitter, and internal filter/field mapping helpers (FilterField, FilterDrawerChipModel interfaces) instead of any/untyped params - filter-drawer-chip.component.ts / filter-drawer-item.component.ts / filter-drawer.component.ts: EventEmitter<any> -> EventEmitter<unknown | Record<string, unknown> | void>, `values: any[]` -> `unknown[]` - filters-wrapper.component.ts: Subject<any> -> Subject<unknown> for runReportEvent/resetReportEvent - pagination.component.ts: `options: any[]` -> concrete option shape matching the template's usage (value/label/disabled/selected) - toolbar.component.ts: EventEmitter<any> -> EventEmitter<ToolbarItem> matching the emitted contentModel item type - aside-toggle.spec.ts / toolbar.spec.ts: `fixture: any` -> ComponentFixture<...> Lowers the root ESLint warning baseline 1274 -> 1259.
Covers the remaining small pockets of unsafe/legacy types outside the larger per-area slices already addressed: formly/sam-formly.ts, type-check-helpers.ts, wrappers, elements, types.ts, pipes, formly/components, filters, typings.d.ts. - sam-formly.ts: AbstractSamFormly is now generic over a SamFormlyTemplateComponent-constrained template type instead of `any`; setProperties/ngOnInit typed against that generic and Record<string, unknown> configuration - type-check-helpers.ts: isString/isObject/isArray/safeTypeOf take `unknown` instead of `any` - types.ts: HistoryNodeType.queryParams -> Record<string, string | number | boolean>, AutocompleteConfig.serviceOptions -> unknown, UploadedFileData.icon -> new UploadedFileIcon interface (matches upload-v2 template's `icon.name`/`icon.iconClass` usage) - typings.d.ts: `*.json` module value -> unknown - elements/button: onClick -> EventEmitter<Event>, click($event) -> click($event: Event), btnClassMap -> Record<string, string>; spec updated to pass real Event instances and typed fixture - wrappers/fieldset-wrapper: errorMessages -> string[], hintContainer -> ElementRef<HTMLElement>, ngOnChanges/onResize/toggleHint/ calculateNumberOfLines/setInvalidError given concrete parameter types; specs updated with typed fixture and a complete SimpleChange mock - wrappers/label-wrapper.spec.ts: typed fixture - filters/filters.component.ts: model -> Record<string, unknown> - pipes/date-time-display: transform(datetime) typed as string | number | Date, returns string | undefined - formly/components/autocomplete/test.service.ts: fetch() -> Observable<unknown> Lowers the root ESLint warning baseline 1259 -> 1231.
fpigeonjr
force-pushed
the
gh-586-replace-unsafe-and-legacy-typescript-types
branch
from
September 3, 2026 18:37
bb6a7ff to
19d4137
Compare
- Rebase branch tip onto latest #675 (gh-582) so this PR's diff/baseline reflect only #586's type-safety changes, not #675's still-open autofix set. #675 is CLEAN/MERGEABLE and independently reviewed; stacking is the documented convention for this repo's slice-based PRs. - Retarget PR base to gh-582-apply-safe-eslint-autofixes-and-lower-the-baseline so the GitHub diff matches (rebase alone doesn't move a PR's base). - Drop the #674 datepicker outside-click fix and #677 sidenav RxJS fix commits from this branch entirely (dropped during rebase) -- both are unrelated bugfixes already merged to master via their own PRs; they were only present here as inherited ancestry from an earlier base choice, not something this PR should carry or take credit for. - pagination.component.ts: options.value widened to 'string | number' -- the template already supports numeric option values via attribute binding; the prior 'any[]' allowed this and the fix's 'string' literal would have narrowed a supported case. - date-time-display.pipe.ts: transform() parameter widened to include 'undefined' explicitly -- the implementation's own guard branch handles undefined and the pipe previously accepted it; the stricter signature would have been a source-compatibility break for existing callers. - types.ts: HistoryNodeType.queryParams value type widened to include readonly arrays and null, matching Angular Router's actual accepted queryParams value shapes (repeated params, param removal) instead of the narrower 'string | number | boolean' which would reject valid existing usage.
fpigeonjr
marked this pull request as ready for review
September 3, 2026 19:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Replaces unsafe/legacy TypeScript types (
@typescript-eslint/no-explicit-any,no-unsafe-function-type) across four small, coherent areas of the codebase, as a first slice of #586:ui-kit/utilities—are-equal.ts,deprecator.ts,key-helper.ts. Added aKeyEventLikeinterface andtoKeyEventLike()guard soKeyHelperno longer needsanyfor malformed/partial event input while staying tolerant of it.ui-kit/directives—taboutside.directive.ts,sticky.component.ts. Added an exportedOffsetParentLikeinterface sosticky.component.ts'sgetElemDistanceToTopcan be typed without assuming a real DOMHTMLElement(specs pass plain mock objects).ui-kit/layout— filter-drawer (dynamic-chips.directive.ts+ chip/item/drawer components),filters-wrapper.component.ts,pagination.component.ts,toolbar.component.ts. AddedFilterField/FilterDrawerChipModelinterfaces; typed emitters asunknown/Record<string, unknown>/ToolbarIteminstead ofany; gavepagination'soptionsinput a concrete inline shape matching its template usage.formly/sam-formly.ts(madeAbstractSamFormlygeneric over a newSamFormlyTemplateComponentconstraint instead of usinganyfor the wrapped template component),type-check-helpers.ts(isString/isObject/isArray/safeTypeOfnow takeunknown),types.ts(HistoryNodeType.queryParams,AutocompleteConfig.serviceOptions, newUploadedFileIconinterface forUploadedFileData.icon),typings.d.ts(*.jsonmodule value →unknown),elements/button(onClick→EventEmitter<Event>,btnClassMap→Record<string, string>),wrappers/fieldset-wrapper(errorMessages→string[],hintContainer→ElementRef<HTMLElement>, handler parameters typed),filters.component.ts(model→Record<string, unknown>),pipes/date-time-display.pipe.ts(transformtyped asstring | number | Date),formly/components/autocomplete/test.service.ts(fetch()→Observable<unknown>).any/Functionto precise or intentionally-generic (unknown,Record<string, unknown>) types.tsc --noEmitdiffing (before/after viagit stash) to confirm no new type errors,eslinton changed files to confirm target rules are resolved without new warnings, and the fulltest-appsuite (152 files / 1386 tests) to confirm no regressions.rootwarning baseline has been lowered after each area:1307 → 1289 → 1274 → 1259 → 1231(this branch was rebased onto Apply safe ESLint autofixes and lower the warning baseline #675'sno-wrapper-object-typesautofixes first, which is why the starting point differs from Replace unsafe and legacy TypeScript types #586's pre-rebase snapshot).This is the first of several planned PRs for #586 — the remaining, larger areas (
layout-deprecated,form-templates,components,experimental,form-controls) are tracked as separate sub-issues linked to #586.Motivation and Context
Progresses #586. Does not close it — several larger areas remain and will be filed as separate sub-issues/PRs.
Type of Change (Select One and Apply Label)
bugfixlabelenhancementlabelbreakinglabelmaintenancelabelHow to Test
npm ci && npm ci --prefix test-appnpm run lint— confirm 0 errors, warnings at/under the new baseline ineslint-baseline.jsonnpx tsc -p tsconfig.json --noEmit— confirm no new compile errorsnpm --prefix test-app test— confirm all 152 spec files / 1386 tests passnpm run format:check— confirm cleanExpected result: All checks pass; ESLint
rootbaseline is1231(down from1259pre-PR /1307pre-rebase); noany/Functionusages remain inui-kit/utilities,ui-kit/directives,ui-kit/layout, or the misc files listed above.Screenshots (if appropriate)
N/A — type-only changes, no UI/visual impact.
Checklist
gh-<number>-<slug>)format:checkpasses (npm run format:check)lintpasses (npm run lint)buildpasses (cd test-app && npm run build)cd test-app && npm test)