diff --git a/goldens/material/snack-bar/index.api.md b/goldens/material/snack-bar/index.api.md index 111d667f63fc..3ec8d9892082 100644 --- a/goldens/material/snack-bar/index.api.md +++ b/goldens/material/snack-bar/index.api.md @@ -32,10 +32,10 @@ import { TemplateRef } from '@angular/core'; import { ViewContainerRef } from '@angular/core'; // @public -export const MAT_SNACK_BAR_DATA: InjectionToken; +export const MAT_SNACK_BAR_DATA: InjectionToken; // @public -export const MAT_SNACK_BAR_DEFAULT_OPTIONS: InjectionToken>; +export const MAT_SNACK_BAR_DEFAULT_OPTIONS: InjectionToken>; // @public @deprecated export function MAT_SNACK_BAR_DEFAULT_OPTIONS_FACTORY(): MatSnackBarConfig; @@ -48,10 +48,10 @@ export class MatSnackBar implements OnDestroy { // (undocumented) ngOnDestroy(): void; open(message: string, action?: string, config?: MatSnackBarConfig): MatSnackBarRef; - get _openedSnackBarRef(): MatSnackBarRef | null; - set _openedSnackBarRef(value: MatSnackBarRef | null); - openFromComponent(component: ComponentType, config?: MatSnackBarConfig): MatSnackBarRef; - openFromTemplate(template: TemplateRef, config?: MatSnackBarConfig): MatSnackBarRef>; + get _openedSnackBarRef(): MatSnackBarRef | null; + set _openedSnackBarRef(value: MatSnackBarRef | null); + openFromComponent(component: ComponentType, config?: MatSnackBarConfig): MatSnackBarRef; + openFromTemplate(template: TemplateRef, config?: MatSnackBarConfig): MatSnackBarRef>; simpleSnackBarComponent: typeof SimpleSnackBar; snackBarContainerComponent: typeof MatSnackBarContainer; // (undocumented) @@ -82,7 +82,7 @@ export const matSnackBarAnimations: { }; // @public -export class MatSnackBarConfig { +export class MatSnackBarConfig { announcementMessage?: string; data?: D | null; direction?: Direction; @@ -174,7 +174,7 @@ export class SimpleSnackBar implements TextOnlySnackBar { constructor(...args: unknown[]); action(): void; // (undocumented) - data: any; + data: TextOnlySnackBarData; get hasAction(): boolean; // (undocumented) snackBarRef: MatSnackBarRef; @@ -189,16 +189,21 @@ export interface TextOnlySnackBar { // (undocumented) action: () => void; // (undocumented) - data: { - message: string; - action: string; - }; + data: TextOnlySnackBarData; // (undocumented) hasAction: boolean; // (undocumented) snackBarRef: MatSnackBarRef; } +// @public +export interface TextOnlySnackBarData { + // (undocumented) + action: string; + // (undocumented) + message: string; +} + // (No @packageDocumentation comment for this package) ``` diff --git a/goldens/material/stepper/index.api.md b/goldens/material/stepper/index.api.md index c4ecf404a356..e61b12fa3f13 100644 --- a/goldens/material/stepper/index.api.md +++ b/goldens/material/stepper/index.api.md @@ -64,7 +64,7 @@ export class MatStep extends CdkStep implements ErrorStateMatcher, AfterContentI export class MatStepContent { constructor(...args: unknown[]); // (undocumented) - _template: TemplateRef; + _template: TemplateRef; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) diff --git a/goldens/material/tabs/index.api.md b/goldens/material/tabs/index.api.md index abe762fdddd8..23dd35c6b1be 100644 --- a/goldens/material/tabs/index.api.md +++ b/goldens/material/tabs/index.api.md @@ -35,13 +35,13 @@ export const _MAT_INK_BAR_POSITIONER: InjectionToken<_MatInkBarPositioner>; export function _MAT_INK_BAR_POSITIONER_FACTORY(): _MatInkBarPositioner; // @public -export const MAT_TAB: InjectionToken; +export const MAT_TAB: InjectionToken; // @public export const MAT_TAB_CONTENT: InjectionToken; // @public -export const MAT_TAB_GROUP: InjectionToken; +export const MAT_TAB_GROUP: InjectionToken; // @public export const MAT_TAB_LABEL: InjectionToken; @@ -143,17 +143,17 @@ export abstract class MatPaginatedTabHeader implements AfterContentChecked, Afte } // @public (undocumented) -export class MatTab implements OnInit, OnChanges, OnDestroy { +export class MatTab implements MatTabBase, OnInit, OnChanges, OnDestroy { constructor(...args: unknown[]); ariaLabel: string; ariaLabelledby: string; bodyClass: string | string[]; // (undocumented) - _closestTabGroup: any; + _closestTabGroup: MatTabGroupBase | null; get content(): TemplatePortal | null; disabled: boolean; id: string | null; - _implicitContent: TemplateRef; + _implicitContent?: TemplateRef; isActive: boolean; labelClass: string | string[]; // (undocumented) @@ -176,6 +176,10 @@ export class MatTab implements OnInit, OnChanges, OnDestroy { static ɵfac: i0.ɵɵFactoryDeclaration; } +// @public +export interface MatTabBase { +} + // @public export class MatTabBody implements OnInit, OnDestroy { constructor(...args: unknown[]); @@ -231,7 +235,7 @@ export class MatTabChangeEvent { export class MatTabContent { constructor(...args: unknown[]); // (undocumented) - template: TemplateRef; + template: TemplateRef; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) @@ -321,6 +325,10 @@ export class MatTabGroup implements AfterViewInit, AfterContentInit, AfterConten static ɵfac: i0.ɵɵFactoryDeclaration; } +// @public +export interface MatTabGroupBase { +} + // @public export interface MatTabGroupBaseHeader { // (undocumented) @@ -368,7 +376,7 @@ export type MatTabHeaderPosition = 'above' | 'below'; // @public export class MatTabLabel extends CdkPortal { // (undocumented) - _closestTab: any; + _closestTab: MatTabBase | null; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration; // (undocumented) diff --git a/goldens/material/timepicker/index.api.md b/goldens/material/timepicker/index.api.md index f563743b636f..7bdda76766a6 100644 --- a/goldens/material/timepicker/index.api.md +++ b/goldens/material/timepicker/index.api.md @@ -94,14 +94,14 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O readonly min: InputSignalWithTransform; // (undocumented) ngOnDestroy(): void; - registerOnChange(fn: (value: any) => void): void; + registerOnChange(fn: (value: unknown) => void): void; registerOnTouched(fn: () => void): void; registerOnValidatorChange(fn: () => void): void; setDisabledState(isDisabled: boolean): void; readonly timepicker: InputSignal>; validate(control: AbstractControl): ValidationErrors | null; readonly value: ModelSignal; - writeValue(value: any): void; + writeValue(value: unknown): void; // (undocumented) static ɵdir: i0.ɵɵDirectiveDeclaration, "input[matTimepicker]", ["matTimepickerInput"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "timepicker": { "alias": "matTimepicker"; "required": true; "isSignal": true; }; "min": { "alias": "matTimepickerMin"; "required": false; "isSignal": true; }; "max": { "alias": "matTimepickerMax"; "required": false; "isSignal": true; }; "disabledInput": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>; // (undocumented) diff --git a/goldens/material/tooltip/index.api.md b/goldens/material/tooltip/index.api.md index d81a8dd9a0b6..9426411c62e4 100644 --- a/goldens/material/tooltip/index.api.md +++ b/goldens/material/tooltip/index.api.md @@ -88,10 +88,10 @@ export class MatTooltip implements OnDestroy, AfterViewInit { y: number; }): void; get tooltipClass(): string | string[] | Set | { - [key: string]: any; + [key: string]: unknown; }; set tooltipClass(value: string | string[] | Set | { - [key: string]: any; + [key: string]: unknown; }); // (undocumented) _tooltipInstance: TooltipComponent | null; @@ -160,7 +160,7 @@ export class TooltipComponent implements OnDestroy { show(delay: number): void; _tooltip: ElementRef; tooltipClass: string | string[] | Set | { - [key: string]: any; + [key: string]: unknown; }; _triggerElement: HTMLElement; // (undocumented) diff --git a/src/material/snack-bar/simple-snack-bar.ts b/src/material/snack-bar/simple-snack-bar.ts index 09070641000e..d80d4f01cbce 100644 --- a/src/material/snack-bar/simple-snack-bar.ts +++ b/src/material/snack-bar/simple-snack-bar.ts @@ -12,11 +12,17 @@ import {MatSnackBarRef} from './snack-bar-ref'; import {MAT_SNACK_BAR_DATA} from './snack-bar-config'; import {MatSnackBarAction, MatSnackBarActions, MatSnackBarLabel} from './snack-bar-content'; +/** Input data for the snack bar. */ +export interface TextOnlySnackBarData { + message: string; + action: string; +} + /** * Interface for a simple snack bar component that has a message and a single action. */ export interface TextOnlySnackBar { - data: {message: string; action: string}; + data: TextOnlySnackBarData; snackBarRef: MatSnackBarRef; action: () => void; hasAction: boolean; @@ -36,7 +42,7 @@ export interface TextOnlySnackBar { }) export class SimpleSnackBar implements TextOnlySnackBar { snackBarRef = inject>(MatSnackBarRef); - data = inject(MAT_SNACK_BAR_DATA); + data = inject(MAT_SNACK_BAR_DATA); constructor(...args: unknown[]); constructor() {} diff --git a/src/material/snack-bar/snack-bar-config.ts b/src/material/snack-bar/snack-bar-config.ts index 1239bc4b1f68..7b1306bea9b4 100644 --- a/src/material/snack-bar/snack-bar-config.ts +++ b/src/material/snack-bar/snack-bar-config.ts @@ -11,7 +11,7 @@ import {AriaLivePoliteness} from '@angular/cdk/a11y'; import {Direction} from '@angular/cdk/bidi'; /** Injection token that can be used to access the data that was passed in to a snack bar. */ -export const MAT_SNACK_BAR_DATA = new InjectionToken('MatSnackBarData'); +export const MAT_SNACK_BAR_DATA = new InjectionToken('MatSnackBarData'); /** Possible values for horizontalPosition on MatSnackBarConfig. */ export type MatSnackBarHorizontalPosition = 'start' | 'center' | 'end' | 'left' | 'right'; @@ -22,7 +22,7 @@ export type MatSnackBarVerticalPosition = 'top' | 'bottom'; /** * Configuration used when opening a snack-bar. */ -export class MatSnackBarConfig { +export class MatSnackBarConfig { /** The politeness level for the MatAriaLiveAnnouncer announcement. */ politeness?: AriaLivePoliteness = 'assertive'; diff --git a/src/material/snack-bar/snack-bar.spec.ts b/src/material/snack-bar/snack-bar.spec.ts index 242722ddae20..464f3ca61ff7 100644 --- a/src/material/snack-bar/snack-bar.spec.ts +++ b/src/material/snack-bar/snack-bar.spec.ts @@ -595,10 +595,11 @@ describe('MatSnackBar', () => { }); it('should be able to inject arbitrary user data', () => { + const data: BurritosNotificationData = { + burritoType: 'Chimichanga', + }; const snackBarRef = snackBar.openFromComponent(BurritosNotification, { - data: { - burritoType: 'Chimichanga', - }, + data, }); expect(snackBarRef.instance.data) @@ -1025,17 +1026,21 @@ class ComponentWithChildViewContainer { `, }) class ComponentWithTemplateRef { - @ViewChild(TemplateRef) templateRef: TemplateRef; + @ViewChild(TemplateRef) templateRef: TemplateRef; localValue: string; } +interface BurritosNotificationData { + burritoType: string; +} + /** Simple component for testing ComponentPortal. */ @Component({ template: '

Burritos are on the way.

', }) class BurritosNotification { snackBarRef = inject>(MatSnackBarRef); - data = inject(MAT_SNACK_BAR_DATA); + data = inject(MAT_SNACK_BAR_DATA); } @Component({ diff --git a/src/material/snack-bar/snack-bar.ts b/src/material/snack-bar/snack-bar.ts index c7e65e3e2b83..ddbb3482f10c 100644 --- a/src/material/snack-bar/snack-bar.ts +++ b/src/material/snack-bar/snack-bar.ts @@ -63,7 +63,7 @@ export class MatSnackBar implements OnDestroy { * If there is a parent snack-bar service, all operations should delegate to that parent * via `_openedSnackBarRef`. */ - private _snackBarRefAtThisLevel: MatSnackBarRef | null = null; + private _snackBarRefAtThisLevel: MatSnackBarRef | null = null; /** The component that should be rendered as the snack bar's simple component. */ simpleSnackBarComponent = SimpleSnackBar; @@ -75,12 +75,12 @@ export class MatSnackBar implements OnDestroy { handsetCssClass = 'mat-mdc-snack-bar-handset'; /** Reference to the currently opened snackbar at *any* level. */ - get _openedSnackBarRef(): MatSnackBarRef | null { + get _openedSnackBarRef(): MatSnackBarRef | null { const parent = this._parentSnackBar; return parent ? parent._openedSnackBarRef : this._snackBarRefAtThisLevel; } - set _openedSnackBarRef(value: MatSnackBarRef | null) { + set _openedSnackBarRef(value: MatSnackBarRef | null) { if (this._parentSnackBar) { this._parentSnackBar._openedSnackBarRef = value; } else { @@ -98,11 +98,11 @@ export class MatSnackBar implements OnDestroy { * @param component Component to be instantiated. * @param config Extra configuration for the snack bar. */ - openFromComponent( + openFromComponent( component: ComponentType, config?: MatSnackBarConfig, ): MatSnackBarRef { - return this._attach(component, config) as MatSnackBarRef; + return this._attach(component, config); } /** @@ -113,9 +113,9 @@ export class MatSnackBar implements OnDestroy { * @param config Extra configuration for the snack bar. */ openFromTemplate( - template: TemplateRef, + template: TemplateRef, config?: MatSnackBarConfig, - ): MatSnackBarRef> { + ): MatSnackBarRef> { return this._attach(template, config); } @@ -187,14 +187,19 @@ export class MatSnackBar implements OnDestroy { /** * Places a new component or a template as the content of the snack bar container. */ + private _attach(content: ComponentType, userConfig?: MatSnackBarConfig): MatSnackBarRef; + private _attach( + content: TemplateRef, + userConfig?: MatSnackBarConfig, + ): MatSnackBarRef>; private _attach( content: ComponentType | TemplateRef, userConfig?: MatSnackBarConfig, - ): MatSnackBarRef> { + ): MatSnackBarRef> { const config = {...new MatSnackBarConfig(), ...this._defaultConfig, ...userConfig}; const overlayRef = this._createOverlay(config); const container = this._attachSnackBarContainer(overlayRef, config); - const snackBarRef = new MatSnackBarRef>(container, overlayRef); + const snackBarRef = new MatSnackBarRef>(container, overlayRef); if (content instanceof TemplateRef) { const portal = new TemplatePortal(content, null!, { @@ -231,11 +236,11 @@ export class MatSnackBar implements OnDestroy { this._animateSnackBar(snackBarRef, config); this._openedSnackBarRef = snackBarRef; - return this._openedSnackBarRef; + return snackBarRef; } /** Animates the old snack bar out and the new one in. */ - private _animateSnackBar(snackBarRef: MatSnackBarRef, config: MatSnackBarConfig) { + private _animateSnackBar(snackBarRef: MatSnackBarRef, config: MatSnackBarConfig) { // When the snackbar is dismissed, clear the reference to it. snackBarRef.afterDismissed().subscribe(() => { // Clear the snackbar ref if it hasn't already been replaced by a newer snackbar. diff --git a/src/material/sort/sort.spec.ts b/src/material/sort/sort.spec.ts index 9828dc91d324..869fbe288c29 100644 --- a/src/material/sort/sort.spec.ts +++ b/src/material/sort/sort.spec.ts @@ -539,8 +539,8 @@ class SimpleMatSortApp { } } -class FakeDataSource extends DataSource { - connect(collectionViewer: CollectionViewer): Observable { +class FakeDataSource extends DataSource { + connect(collectionViewer: CollectionViewer): Observable { return collectionViewer.viewChange.pipe(map(() => [])); } disconnect() {} diff --git a/src/material/stepper/step-content.ts b/src/material/stepper/step-content.ts index 8328c0d10f5e..1bec41580fb3 100644 --- a/src/material/stepper/step-content.ts +++ b/src/material/stepper/step-content.ts @@ -15,7 +15,7 @@ import {Directive, TemplateRef, inject} from '@angular/core'; selector: 'ng-template[matStepContent]', }) export class MatStepContent { - _template = inject>(TemplateRef); + _template = inject>(TemplateRef); constructor(...args: unknown[]); constructor() {} diff --git a/src/material/stepper/stepper.spec.ts b/src/material/stepper/stepper.spec.ts index 287f9dcb2327..bf80d91d0799 100644 --- a/src/material/stepper/stepper.spec.ts +++ b/src/material/stepper/stepper.spec.ts @@ -1641,7 +1641,7 @@ describe('MatStepper', () => { /** Asserts that keyboard interaction works correctly. */ function assertCorrectKeyboardInteraction( - fixture: ComponentFixture, + fixture: ComponentFixture, stepHeaders: DebugElement[], orientation: StepperOrientation, ) { @@ -1742,7 +1742,7 @@ function assertCorrectKeyboardInteraction( /** Asserts that arrow key direction works correctly in RTL mode. */ function assertArrowKeyInteractionInRtl( - fixture: ComponentFixture, + fixture: ComponentFixture, stepHeaders: DebugElement[], ) { const stepperComponent = fixture.debugElement.query(By.directive(MatStepper))!.componentInstance; @@ -1764,7 +1764,7 @@ function assertArrowKeyInteractionInRtl( /** Asserts that keyboard interaction works correctly when the user is pressing a modifier key. */ function assertSelectKeyWithModifierInteraction( - fixture: ComponentFixture, + fixture: ComponentFixture, stepHeaders: DebugElement[], orientation: StepperOrientation, selectionKey: number, @@ -1823,7 +1823,7 @@ function asyncValidator(minLength: number, validationTrigger: Subject): As function createComponent( component: Type, providers: Provider[] = [], - imports: any[] = [], + imports: unknown[] = [], encapsulation?: ViewEncapsulation, declarations = [component], ): ComponentFixture { diff --git a/src/material/table/table-data-source.ts b/src/material/table/table-data-source.ts index c19e8e1e921a..debfe0b71933 100644 --- a/src/material/table/table-data-source.ts +++ b/src/material/table/table-data-source.ts @@ -229,10 +229,14 @@ export class MatTableDataSource extend * @returns Whether the filter matches against the data */ filterPredicate: (data: T, filter: string) => boolean = (data: T, filter: string): boolean => { + if ((typeof ngDevMode === 'undefined' || ngDevMode) && typeof data !== 'object') { + throw new Error('Default implementation of filterPredicate requires data to be object.'); + } + // Transform the filter by converting it to lowercase and removing whitespace. const transformedFilter = filter.trim().toLowerCase(); // Loops over the values in the array and returns true if any of them match the filter string - return Object.values(data as {[key: string]: any}).some(value => + return Object.values(data as object).some(value => `${value}`.toLowerCase().includes(transformedFilter), ); }; diff --git a/src/material/table/table.spec.ts b/src/material/table/table.spec.ts index 6dfee1ccceb8..3db742939b0d 100644 --- a/src/material/table/table.spec.ts +++ b/src/material/table/table.spec.ts @@ -45,9 +45,9 @@ describe('MatTable', () => { const data = fixture.componentInstance.dataSource!.data; expectTableToMatchContent(tableElement, [ ['Column A', 'Column B', 'Column C'], - [data[0].a, data[0].b, data[0].c], - [data[1].a, data[1].b, data[1].c], - [data[2].a, data[2].b, data[2].c], + [data[0].a, data[0].b, data[0].c] as string[], + [data[1].a, data[1].b, data[1].c] as string[], + [data[2].a, data[2].b, data[2].c] as string[], ['fourth_row'], ['Footer A', 'Footer B', 'Footer C'], ]); @@ -93,10 +93,10 @@ describe('MatTable', () => { const data = fixture.componentInstance.dataSource!.data; expectTableToMatchContent(tableElement, [ ['Column A', 'Column B', 'Column C'], - [data[0].a, data[0].b, data[0].c], - [data[1].a, data[1].b, data[1].c], - [data[2].a, data[2].b, data[2].c], - [data[3].a, data[3].b, data[3].c], + [data[0].a, data[0].b, data[0].c] as string[], + [data[1].a, data[1].b, data[1].c] as string[], + [data[2].a, data[2].b, data[2].c] as string[], + [data[3].a, data[3].b, data[3].c] as string[], ]); }); @@ -188,9 +188,9 @@ describe('MatTable', () => { const data = fixture.componentInstance.dataSource!.data; expectTableToMatchContent(tableElement, [ ['Column A', 'Column B', 'Column C'], - [data[0].a, data[0].b, data[0].c], - [data[1].a, data[1].b, data[1].c], - [data[2].a, data[2].b, data[2].c], + [data[0].a, data[0].b, data[0].c] as string[], + [data[1].a, data[1].b, data[1].c] as string[], + [data[2].a, data[2].b, data[2].c] as string[], ]); }); @@ -202,9 +202,9 @@ describe('MatTable', () => { const data = fixture.componentInstance.dataSource!.data; expectTableToMatchContent(tableElement, [ ['Column A', 'Column B', 'Column C'], - [data[0].a, data[0].b, data[0].c], - [data[1].a, data[1].b, data[1].c], - [data[2].a, data[2].b, data[2].c], + [data[0].a, data[0].b, data[0].c] as string[], + [data[1].a, data[1].b, data[1].c] as string[], + [data[2].a, data[2].b, data[2].c] as string[], ]); }); @@ -386,7 +386,7 @@ describe('MatTable', () => { ]); // Change the filter to a falsy value that might come in from the view. - dataSource.filter = 0 as any; + dataSource.filter = 0 as unknown as string; flushMicrotasks(); fixture.detectChanges(); expectTableToMatchContent(tableElement, [ @@ -633,7 +633,7 @@ describe('MatTable', () => { ['Footer A', 'Footer B', 'Footer C'], ]); - dataSource.data = {} as any; + dataSource.data = {} as TestData[]; fixture.changeDetectorRef.markForCheck(); fixture.detectChanges(); expectTableToMatchContent(tableElement, [ @@ -1137,7 +1137,7 @@ function getActualTableContent(tableElement: Element): string[][] { return actualTableContent.map(row => row.map(cell => cell.textContent!.trim())); } -export function expectTableToMatchContent(tableElement: Element, expected: any[]) { +export function expectTableToMatchContent(tableElement: Element, expected: string[][]) { const missedExpectations: string[] = []; function checkCellContent(actualCell: string, expectedCell: string) { if (actualCell !== expectedCell) { @@ -1163,7 +1163,7 @@ export function expectTableToMatchContent(tableElement: Element, expected: any[] } row.forEach((actualCell, cellIndex) => { - const expectedCell = expectedRow ? expectedRow[cellIndex] : null; + const expectedCell = expectedRow[cellIndex]; checkCellContent(actualCell, expectedCell); }); }); diff --git a/src/material/tabs/public-api.ts b/src/material/tabs/public-api.ts index d7b4df8e9ba1..088ddc6291f4 100644 --- a/src/material/tabs/public-api.ts +++ b/src/material/tabs/public-api.ts @@ -16,8 +16,10 @@ export { } from './tab-body'; export {MatTabsConfig, MAT_TABS_CONFIG} from './tab-config'; export {MatTabContent, MAT_TAB_CONTENT} from './tab-content'; -export {MatTabLabel, MAT_TAB, MAT_TAB_LABEL} from './tab-label'; -export {MatTab, MAT_TAB_GROUP} from './tab'; +export {MatTabLabel, MAT_TAB_LABEL} from './tab-label'; +export {MatTab} from './tab'; +export {MAT_TAB, MatTabBase} from './tab-token'; +export {MAT_TAB_GROUP, MatTabGroupBase} from './tab-group-token'; export { MatInkBar, _MatInkBarPositioner, diff --git a/src/material/tabs/tab-body.spec.ts b/src/material/tabs/tab-body.spec.ts index 8cf271e1665c..39c9e2b014e8 100644 --- a/src/material/tabs/tab-body.spec.ts +++ b/src/material/tabs/tab-body.spec.ts @@ -160,7 +160,7 @@ class SimpleTabBodyApp implements AfterViewInit { position: number; @ViewChild(MatTabBody) tabBody: MatTabBody; - @ViewChild(TemplateRef) template: TemplateRef; + @ViewChild(TemplateRef) template: TemplateRef; private readonly _viewContainerRef = inject(ViewContainerRef); diff --git a/src/material/tabs/tab-content.ts b/src/material/tabs/tab-content.ts index f148342fdad0..c27a74065185 100644 --- a/src/material/tabs/tab-content.ts +++ b/src/material/tabs/tab-content.ts @@ -21,7 +21,7 @@ export const MAT_TAB_CONTENT = new InjectionToken('MatTabContent' providers: [{provide: MAT_TAB_CONTENT, useExisting: MatTabContent}], }) export class MatTabContent { - template = inject>(TemplateRef); + template = inject>(TemplateRef); constructor(...args: unknown[]); constructor() {} diff --git a/src/material/tabs/tab-group-token.ts b/src/material/tabs/tab-group-token.ts new file mode 100644 index 000000000000..b55cbeea6f6e --- /dev/null +++ b/src/material/tabs/tab-group-token.ts @@ -0,0 +1,13 @@ +import {InjectionToken} from '@angular/core'; + +/** + * Used to provide a tab group without causing a circular dependency. + * @docs-private + */ +export interface MatTabGroupBase {} + +/** + * Used to provide a tab group without causing a circular dependency. + * @docs-private + */ +export const MAT_TAB_GROUP = new InjectionToken('MAT_TAB_GROUP'); diff --git a/src/material/tabs/tab-group.spec.ts b/src/material/tabs/tab-group.spec.ts index 9110f76ebc9b..bf6282e4aa85 100644 --- a/src/material/tabs/tab-group.spec.ts +++ b/src/material/tabs/tab-group.spec.ts @@ -12,7 +12,7 @@ import { } from '@angular/core/testing'; import {By} from '@angular/platform-browser'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {Observable} from 'rxjs'; +import {Observable, Subscriber} from 'rxjs'; import { MAT_TABS_CONFIG, MatTab, @@ -20,6 +20,7 @@ import { MatTabHeader, MatTabHeaderPosition, MatTabsModule, + MatTabChangeEvent, } from './index'; describe('MatTabGroup', () => { @@ -1034,7 +1035,7 @@ describe('MatTabGroup', () => { * Checks that the `selectedIndex` has been updated; checks that the label and body have their * respective `active` classes */ - function checkSelectedIndex(expectedIndex: number, fixture: ComponentFixture) { + function checkSelectedIndex(expectedIndex: number, fixture: ComponentFixture) { fixture.detectChanges(); let tabComponent: MatTabGroup = fixture.debugElement.query( @@ -1053,11 +1054,11 @@ describe('MatTabGroup', () => { expect(tabContentElement.classList.contains('mat-mdc-tab-body-active')).toBe(true); } - function getSelectedLabel(fixture: ComponentFixture): HTMLElement { + function getSelectedLabel(fixture: ComponentFixture): HTMLElement { return fixture.nativeElement.querySelector('.mdc-tab--active'); } - function getSelectedContent(fixture: ComponentFixture): HTMLElement { + function getSelectedContent(fixture: ComponentFixture): HTMLElement { return fixture.nativeElement.querySelector('.mat-mdc-tab-body-active'); } }); @@ -1291,18 +1292,18 @@ class SimpleTabsTestApp { @ViewChild(MatTabGroup) tabGroup: MatTabGroup; @ViewChildren(MatTab) tabs: QueryList; selectedIndex: number = 1; - focusEvent: any; - selectEvent: any; + focusEvent: MatTabChangeEvent; + selectEvent: MatTabChangeEvent; disableRipple: boolean = false; contentTabIndex: number | null = null; headerPosition: MatTabHeaderPosition = 'above'; ariaLabel: string; ariaLabelledby: string; secondTabId: string | null = null; - handleFocus(event: any) { + handleFocus(event: MatTabChangeEvent) { this.focusEvent = event; } - handleSelection(event: any) { + handleSelection(event: MatTabChangeEvent) { this.selectEvent = event; } animationDone() {} @@ -1332,13 +1333,13 @@ class SimpleDynamicTabsTestApp { {label: 'Label 3', content: 'Content 3'}, ]; selectedIndex: number = 1; - focusEvent: any; - selectEvent: any; + focusEvent: MatTabChangeEvent; + selectEvent: MatTabChangeEvent; disablePagination = false; - handleFocus(event: any) { + handleFocus(event: MatTabChangeEvent) { this.focusEvent = event; } - handleSelection(event: any) { + handleSelection(event: MatTabChangeEvent) { this.selectEvent = event; } } @@ -1412,11 +1413,11 @@ class AsyncTabsTestApp implements OnInit { {label: 'two', content: 'two'}, ]; - tabs: Observable; + tabs: Observable; ngOnInit() { // Use ngOnInit because there is some issue with scheduling the async task in the constructor. - this.tabs = new Observable((observer: any) => { + this.tabs = new Observable((observer: Subscriber) => { setTimeout(() => observer.next(this._tabs)); }); } @@ -1437,7 +1438,7 @@ class TabGroupWithSimpleApi { preserveContent = false; otherLabel = 'Fruit'; otherContent = 'Apples, grapes'; - @ViewChild('legumes') legumes: any; + @ViewChild('legumes') legumes: HTMLParagraphElement; } @Component({ diff --git a/src/material/tabs/tab-group.ts b/src/material/tabs/tab-group.ts index c71f872f5245..8f32b617e1a5 100644 --- a/src/material/tabs/tab-group.ts +++ b/src/material/tabs/tab-group.ts @@ -28,7 +28,7 @@ import { AfterViewInit, NgZone, } from '@angular/core'; -import {MAT_TAB_GROUP, MatTab} from './tab'; +import {MatTab} from './tab'; import {MatTabHeader} from './tab-header'; import {ThemePalette, MatRipple, _animationsDisabled} from '../core'; import {merge, Subscription} from 'rxjs'; @@ -39,6 +39,7 @@ import {MatTabBody} from './tab-body'; import {CdkPortalOutlet} from '@angular/cdk/portal'; import {MatTabLabelWrapper} from './tab-label-wrapper'; import {Platform} from '@angular/cdk/platform'; +import {MAT_TAB_GROUP} from './tab-group-token'; /** @docs-private */ export interface MatTabGroupBaseHeader { diff --git a/src/material/tabs/tab-header.spec.ts b/src/material/tabs/tab-header.spec.ts index 06705a3c6711..e4b603e23105 100644 --- a/src/material/tabs/tab-header.spec.ts +++ b/src/material/tabs/tab-header.spec.ts @@ -699,7 +699,7 @@ describe('MatTabHeader', () => { spyOn(TestBed.inject(MutationObserverFactory), 'create').and.callFake( (callback: Function) => { mutationCallbacks.push(callback); - return {observe: () => {}, disconnect: () => {}} as any; + return {observe: () => {}, disconnect: () => {}} as unknown as MutationObserver; }, ); diff --git a/src/material/tabs/tab-label.ts b/src/material/tabs/tab-label.ts index dff42617d012..c8bb104fad20 100644 --- a/src/material/tabs/tab-label.ts +++ b/src/material/tabs/tab-label.ts @@ -8,6 +8,7 @@ import {Directive, InjectionToken, inject} from '@angular/core'; import {CdkPortal} from '@angular/cdk/portal'; +import {MAT_TAB} from './tab-token'; /** * Injection token that can be used to reference instances of `MatTabLabel`. It serves as @@ -16,12 +17,6 @@ import {CdkPortal} from '@angular/cdk/portal'; */ export const MAT_TAB_LABEL = new InjectionToken('MatTabLabel'); -/** - * Used to provide a tab label to a tab without causing a circular dependency. - * @docs-private - */ -export const MAT_TAB = new InjectionToken('MAT_TAB'); - /** Used to flag tab labels for use with the portal directive */ @Directive({ selector: '[mat-tab-label], [matTabLabel]', diff --git a/src/material/tabs/tab-token.ts b/src/material/tabs/tab-token.ts new file mode 100644 index 000000000000..d7a91a5123a2 --- /dev/null +++ b/src/material/tabs/tab-token.ts @@ -0,0 +1,13 @@ +import {InjectionToken} from '@angular/core'; + +/** + * Used to provide a tab without causing a circular dependency. + * @docs-private + */ +export interface MatTabBase {} + +/** + * Used to provide a tab without causing a circular dependency. + * @docs-private + */ +export const MAT_TAB = new InjectionToken('MAT_TAB'); diff --git a/src/material/tabs/tab.ts b/src/material/tabs/tab.ts index e54b106c610a..24a0f891564d 100644 --- a/src/material/tabs/tab.ts +++ b/src/material/tabs/tab.ts @@ -24,17 +24,13 @@ import { inject, } from '@angular/core'; import {MatTabContent} from './tab-content'; -import {MAT_TAB, MatTabLabel} from './tab-label'; +import {MatTabLabel} from './tab-label'; import {TemplatePortal} from '@angular/cdk/portal'; import {Subject} from 'rxjs'; import {_CdkPrivateStyleLoader} from '@angular/cdk/private'; import {_StructuralStylesLoader} from '../core'; - -/** - * Used to provide a tab group to a tab without causing a circular dependency. - * @docs-private - */ -export const MAT_TAB_GROUP = new InjectionToken('MAT_TAB_GROUP'); +import {MAT_TAB, MatTabBase} from './tab-token'; +import {MAT_TAB_GROUP} from './tab-group-token'; @Component({ selector: 'mat-tab', @@ -56,7 +52,7 @@ export const MAT_TAB_GROUP = new InjectionToken('MAT_TAB_GROUP'); '[attr.id]': 'null', }, }) -export class MatTab implements OnInit, OnChanges, OnDestroy { +export class MatTab implements MatTabBase, OnInit, OnChanges, OnDestroy { private _viewContainerRef = inject(ViewContainerRef); _closestTabGroup = inject(MAT_TAB_GROUP, {optional: true}); @@ -78,11 +74,10 @@ export class MatTab implements OnInit, OnChanges, OnDestroy { * Template provided in the tab content that will be used if present, used to enable lazy-loading */ @ContentChild(MatTabContent, {read: TemplateRef, static: true}) - // We need an initializer here to avoid a TS error. The value will be set in `ngAfterViewInit`. - private _explicitContent: TemplateRef = undefined!; + private _explicitContent?: TemplateRef; /** Template inside the MatTab view that contains an ``. */ - @ViewChild(TemplateRef, {static: true}) _implicitContent: TemplateRef; + @ViewChild(TemplateRef, {static: true}) _implicitContent?: TemplateRef; /** Plain text label for the tab, used when there is no template label. */ @Input('label') textLabel: string = ''; @@ -154,7 +149,7 @@ export class MatTab implements OnInit, OnChanges, OnDestroy { ngOnInit(): void { this._contentPortal = new TemplatePortal( - this._explicitContent || this._implicitContent, + this._explicitContent || this._implicitContent!, this._viewContainerRef, ); } diff --git a/src/material/timepicker/timepicker-input.ts b/src/material/timepicker/timepicker-input.ts index 3912a236e2d8..3a4fcd4c7e08 100644 --- a/src/material/timepicker/timepicker-input.ts +++ b/src/material/timepicker/timepicker-input.ts @@ -86,7 +86,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O private _dateFormats = inject(MAT_DATE_FORMATS, {optional: true})!; private _formField = inject(MAT_FORM_FIELD, {optional: true}); - private _onChange: ((value: any) => void) | undefined; + private _onChange: ((value: unknown) => void) | undefined; private _onTouched: (() => void) | undefined; private _validatorOnChange: (() => void) | undefined; private _cleanupClick: () => void; @@ -183,7 +183,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O * Implemented as a part of `ControlValueAccessor`. * @docs-private */ - writeValue(value: any): void { + writeValue(value: unknown): void { // Note that we need to deserialize here, rather than depend on the value change effect, // because `getValidDateOrNull` will clobber the value if it's parseable, but not created by // the current adapter (see #30140). @@ -195,7 +195,7 @@ export class MatTimepickerInput implements ControlValueAccessor, Validator, O * Implemented as a part of `ControlValueAccessor`. * @docs-private */ - registerOnChange(fn: (value: any) => void): void { + registerOnChange(fn: (value: unknown) => void): void { this._onChange = fn; } diff --git a/src/material/tooltip/tooltip.spec.ts b/src/material/tooltip/tooltip.spec.ts index fccac2350c6b..d008666a7805 100644 --- a/src/material/tooltip/tooltip.spec.ts +++ b/src/material/tooltip/tooltip.spec.ts @@ -1423,7 +1423,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const styles = fixture.nativeElement.querySelector('button').style; - expect(styles.touchAction || (styles as any).webkitUserDrag).toBe('none'); + expect(styles.touchAction || styles.webkitUserDrag).toBe('none'); }); it('should allow native touch interactions if touch gestures are turned off', () => { @@ -1432,7 +1432,7 @@ describe('MatTooltip', () => { fixture.detectChanges(); const styles = fixture.nativeElement.querySelector('button').style; - expect(styles.touchAction || (styles as any).webkitUserDrag).toBeFalsy(); + expect(styles.touchAction || styles.webkitUserDrag).toBeFalsy(); }); it('should allow text selection on inputs when gestures are set to auto', () => { @@ -1444,13 +1444,13 @@ describe('MatTooltip', () => { expect(inputStyle.userSelect).toBeFalsy(); expect(inputStyle.webkitUserSelect).toBeFalsy(); - expect((inputStyle as any).msUserSelect).toBeFalsy(); - expect((inputStyle as any).MozUserSelect).toBeFalsy(); + expect(inputStyle.msUserSelect).toBeFalsy(); + expect(inputStyle.MozUserSelect).toBeFalsy(); expect(textareaStyle.userSelect).toBeFalsy(); expect(textareaStyle.webkitUserSelect).toBeFalsy(); - expect((textareaStyle as any).msUserSelect).toBeFalsy(); - expect((textareaStyle as any).MozUserSelect).toBeFalsy(); + expect(textareaStyle.msUserSelect).toBeFalsy(); + expect(textareaStyle.MozUserSelect).toBeFalsy(); }); it('should disable text selection on inputs when gestures are set to on', () => { @@ -1462,14 +1462,14 @@ describe('MatTooltip', () => { const inputUserSelect = inputStyle.userSelect || inputStyle.webkitUserSelect || - (inputStyle as any).msUserSelect || - (inputStyle as any).MozUserSelect; + inputStyle.msUserSelect || + inputStyle.MozUserSelect; const textareaStyle = fixture.componentInstance.textarea.nativeElement.style; const textareaUserSelect = textareaStyle.userSelect || textareaStyle.webkitUserSelect || - (textareaStyle as any).msUserSelect || - (textareaStyle as any).MozUserSelect; + textareaStyle.msUserSelect || + textareaStyle.MozUserSelect; expect(inputUserSelect).toBe('none'); expect(textareaUserSelect).toBe('none'); @@ -1608,7 +1608,7 @@ describe('MatTooltip', () => { }) class BasicTooltipDemo { position = 'below'; - message: any = initialTooltipMessage; + message: string | number = initialTooltipMessage; showButton = true; showTooltipClass = false; tooltipDisabled = false; @@ -1725,7 +1725,7 @@ class TooltipOnDraggableElement { standalone: false, }) class TooltipDemoWithoutPositionBinding { - message: any = initialTooltipMessage; + message: string = initialTooltipMessage; @ViewChild(MatTooltip) tooltip: MatTooltip; @ViewChild('button') button: ElementRef; } @@ -1749,7 +1749,7 @@ class TooltipDemoWithoutTooltipClassBinding { standalone: false, }) class TooltipDemoWithTooltipClassBinding { - message: any = initialTooltipMessage; + message: string = initialTooltipMessage; @ViewChild(MatTooltip) tooltip: MatTooltip; @ViewChild('button') button: ElementRef; } diff --git a/src/material/tooltip/tooltip.ts b/src/material/tooltip/tooltip.ts index ccd75286af37..239b677a8e2f 100644 --- a/src/material/tooltip/tooltip.ts +++ b/src/material/tooltip/tooltip.ts @@ -52,6 +52,15 @@ import {ComponentPortal} from '@angular/cdk/portal'; import {Observable, Subject} from 'rxjs'; import {_animationsDisabled} from '../core'; +declare global { + interface CSSStyleDeclaration { + msUserSelect: string; + MozUserSelect: string; + webkitUserDrag: string; + webkitTapHighlightColor: string; + } +} + /** Possible positions for a tooltip. */ export type TooltipPosition = 'left' | 'right' | 'above' | 'below' | 'before' | 'after'; @@ -219,7 +228,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit { private _position: TooltipPosition = 'below'; private _positionAtOrigin: boolean = false; private _disabled: boolean = false; - private _tooltipClass: string | string[] | Set | {[key: string]: any}; + private _tooltipClass: string | string[] | Set | {[key: string]: unknown}; private _viewInitialized = false; private _pointerExitEventsInitialized = false; private readonly _tooltipComponent = TooltipComponent; @@ -361,7 +370,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit { return this._tooltipClass; } - set tooltipClass(value: string | string[] | Set | {[key: string]: any}) { + set tooltipClass(value: string | string[] | Set | {[key: string]: unknown}) { this._tooltipClass = value; if (this._tooltipInstance) { this._setTooltipClass(this._tooltipClass); @@ -723,7 +732,9 @@ export class MatTooltip implements OnDestroy, AfterViewInit { } /** Updates the tooltip class */ - private _setTooltipClass(tooltipClass: string | string[] | Set | {[key: string]: any}) { + private _setTooltipClass( + tooltipClass: string | string[] | Set | {[key: string]: unknown}, + ) { if (this._tooltipInstance) { this._tooltipInstance.tooltipClass = tooltipClass; this._tooltipInstance._markForCheck(); @@ -911,20 +922,20 @@ export class MatTooltip implements OnDestroy, AfterViewInit { // textareas, because it prevents the user from typing into them on iOS Safari. if (gestures === 'on' || (element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA')) { style.userSelect = - (style as any).msUserSelect = + style.msUserSelect = style.webkitUserSelect = - (style as any).MozUserSelect = + style.MozUserSelect = 'none'; } // If we have `auto` gestures and the element uses native HTML dragging, // we don't set `-webkit-user-drag` because it prevents the native behavior. if (gestures === 'on' || !element.draggable) { - (style as any).webkitUserDrag = 'none'; + style.webkitUserDrag = 'none'; } style.touchAction = 'none'; - (style as any).webkitTapHighlightColor = 'transparent'; + style.webkitTapHighlightColor = 'transparent'; } } @@ -985,7 +996,7 @@ export class TooltipComponent implements OnDestroy { message: string; /** Classes to be added to the tooltip. Supports the same syntax as `ngClass`. */ - tooltipClass: string | string[] | Set | {[key: string]: any}; + tooltipClass: string | string[] | Set | {[key: string]: unknown}; /** The timeout ID of any current timer set to show the tooltip */ private _showTimeoutId: ReturnType | undefined; diff --git a/src/material/tree/node.ts b/src/material/tree/node.ts index ef7c17a1d970..d88c18db27e1 100644 --- a/src/material/tree/node.ts +++ b/src/material/tree/node.ts @@ -31,7 +31,7 @@ import {NoopTreeKeyManager, TreeKeyManagerItem, TreeKeyManagerStrategy} from '@a function isNoopTreeKeyManager( keyManager: TreeKeyManagerStrategy, ): keyManager is NoopTreeKeyManager { - return !!(keyManager as any)._isNoopTreeKeyManager; + return !!(keyManager as NoopTreeKeyManager)._isNoopTreeKeyManager; } /** diff --git a/src/material/tree/tree-using-tree-control.spec.ts b/src/material/tree/tree-using-tree-control.spec.ts index 2bb9875a4b73..a3c61e706103 100644 --- a/src/material/tree/tree-using-tree-control.spec.ts +++ b/src/material/tree/tree-using-tree-control.spec.ts @@ -18,14 +18,17 @@ import { MatTreeNestedDataSource, } from './index'; +type NodeContent = string[]; +type TreeContent = NodeContent[]; + describe('MatTree', () => { /** Represents an indent for expectNestedTreeToMatch */ - const _ = {}; + const _ = ''; let treeElement: HTMLElement; let underlyingDataSource: FakeDataSource; - function configureMatTreeTestingModule(declarations: Type[]) { + function configureMatTreeTestingModule(declarations: Type[]) { TestBed.configureTestingModule({ imports: [MatTreeModule], declarations: declarations, @@ -786,11 +789,11 @@ function getNodes(treeElement: Element): HTMLElement[] { function expectFlatTreeToMatch( treeElement: Element, expectedPaddingIndent: number = 28, - ...expectedTree: any[] + ...expectedTree: TreeContent ) { const missedExpectations: string[] = []; - function checkNode(node: Element, expectedNode: any[]) { + function checkNode(node: Element, expectedNode: NodeContent) { const actualTextContent = node.textContent!.trim(); const expectedTextContent = expectedNode[expectedNode.length - 1]; if (actualTextContent !== expectedTextContent) { @@ -800,7 +803,7 @@ function expectFlatTreeToMatch( } } - function checkLevel(node: Element, expectedNode: any[]) { + function checkLevel(node: Element, expectedNode: NodeContent) { const rawLevel = (node as HTMLElement).style.paddingLeft; // Some browsers return 0, while others return 0px. @@ -820,7 +823,7 @@ function expectFlatTreeToMatch( } getNodes(treeElement).forEach((node, index) => { - const expected = expectedTree ? expectedTree[index] : null; + const expected = expectedTree[index]; checkLevel(node, expected); checkNode(node, expected); @@ -831,9 +834,9 @@ function expectFlatTreeToMatch( } } -function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { +function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: TreeContent) { const missedExpectations: string[] = []; - function checkNodeContent(node: Element, expectedNode: any[]) { + function checkNodeContent(node: Element, expectedNode: NodeContent) { const expectedTextContent = expectedNode[expectedNode.length - 1]; const actualTextContent = node.childNodes.item(0).textContent!.trim(); if (actualTextContent !== expectedTextContent) { @@ -843,7 +846,7 @@ function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { } } - function checkNodeDescendants(node: Element, expectedNode: any[], currentIndex: number) { + function checkNodeDescendants(node: Element, expectedNode: NodeContent, currentIndex: number) { let expectedDescendant = 0; for (let i = currentIndex + 1; i < expectedTree.length; ++i) { @@ -863,7 +866,7 @@ function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { } getNodes(treeElement).forEach((node, index) => { - const expected = expectedTree ? expectedTree[index] : null; + const expected = expectedTree[index]; checkNodeDescendants(node, expected, index); checkNodeContent(node, expected); diff --git a/src/material/tree/tree.spec.ts b/src/material/tree/tree.spec.ts index 1a62d6b1505b..72e156d29873 100644 --- a/src/material/tree/tree.spec.ts +++ b/src/material/tree/tree.spec.ts @@ -11,14 +11,17 @@ import {BehaviorSubject, Observable} from 'rxjs'; import {map} from 'rxjs/operators'; import {MatTree, MatTreeModule, MatTreeNestedDataSource} from './index'; +type NodeContent = string[]; +type TreeContent = NodeContent[]; + describe('MatTree', () => { /** Represents an indent for expectNestedTreeToMatch */ - const _ = {}; + const _ = ''; let treeElement: HTMLElement; let underlyingDataSource: FakeDataSource; - function configureMatTreeTestingModule(declarations: Type[]) { + function configureMatTreeTestingModule(declarations: Type[]) { TestBed.configureTestingModule({ imports: [MatTreeModule], declarations: declarations, @@ -785,11 +788,11 @@ function getNodes(treeElement: Element): HTMLElement[] { function expectFlatTreeToMatch( treeElement: Element, expectedPaddingIndent: number = 28, - ...expectedTree: any[] + ...expectedTree: TreeContent ) { const missedExpectations: string[] = []; - function checkNode(node: Element, expectedNode: any[]) { + function checkNode(node: Element, expectedNode: NodeContent) { const actualTextContent = node.textContent!.trim(); const expectedTextContent = expectedNode[expectedNode.length - 1]; if (actualTextContent !== expectedTextContent) { @@ -799,7 +802,7 @@ function expectFlatTreeToMatch( } } - function checkLevel(node: Element, expectedNode: any[]) { + function checkLevel(node: Element, expectedNode: NodeContent) { const rawLevel = (node as HTMLElement).style.paddingLeft; // Some browsers return 0, while others return 0px. @@ -819,7 +822,7 @@ function expectFlatTreeToMatch( } getNodes(treeElement).forEach((node, index) => { - const expected = expectedTree ? expectedTree[index] : null; + const expected = expectedTree[index]; checkLevel(node, expected); checkNode(node, expected); @@ -830,9 +833,9 @@ function expectFlatTreeToMatch( } } -function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { +function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: TreeContent) { const missedExpectations: string[] = []; - function checkNodeContent(node: Element, expectedNode: any[]) { + function checkNodeContent(node: Element, expectedNode: NodeContent) { const expectedTextContent = expectedNode[expectedNode.length - 1]; const actualTextContent = node.childNodes.item(0).textContent!.trim(); if (actualTextContent !== expectedTextContent) { @@ -842,7 +845,7 @@ function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { } } - function checkNodeDescendants(node: Element, expectedNode: any[], currentIndex: number) { + function checkNodeDescendants(node: Element, expectedNode: NodeContent, currentIndex: number) { let expectedDescendant = 0; for (let i = currentIndex + 1; i < expectedTree.length; ++i) { @@ -862,7 +865,7 @@ function expectNestedTreeToMatch(treeElement: Element, ...expectedTree: any[]) { } getNodes(treeElement).forEach((node, index) => { - const expected = expectedTree ? expectedTree[index] : null; + const expected = expectedTree[index]; checkNodeDescendants(node, expected, index); checkNodeContent(node, expected);