Skip to content

Commit 3e5e9db

Browse files
devversionmmalerba
authored andcommitted
fix(cdk/scrolling): expand type for "cdkVirtualForOf" input to… (#17421)
Currently the `cdkVirtualForOf` input accepts `null` or `undefined` as valid values. Although when using strict template input type checking (which will be supported by `ngtsc`), passing `null` or `undefined` with strict null checks enabled causes a type check failure because the type definition of the input becomes too strict with "--strictNullChecks" enabled. For extra content: by default if strict null checks are not enabled, `null` or `undefined` are assignable to _every_ type. The current type definiton of the `cdkVirtualForOf` input is incorrectly making the assumption that `null` or `undefined` are always assignable. The type of the input needs to be expanded to explicitly accept `null` or `undefined` to behave consistently regardless of the `strictNullChecks` flag. A common scenario where this breaks is the use of `cdkVirtualFor` in combination with the async pipe from `@angular/common`. This is because the async pipe returns `null` until a value has been emitted. This means that with strict null checks, the type checking will fail because `null` is not allowed. This is similar to what we did for `ngFor` in framework: angular/angular@c1bb886 Fixes #17411
1 parent 5c752c2 commit 3e5e9db

File tree

2 files changed

+8
-6
lines changed

2 files changed

+8
-6
lines changed

src/cdk/scrolling/virtual-for-of.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,18 @@ export class CdkVirtualForOf<T> implements CollectionViewer, DoCheck, OnDestroy
8383

8484
/** The DataSource to display. */
8585
@Input()
86-
get cdkVirtualForOf(): DataSource<T> | Observable<T[]> | NgIterable<T> {
86+
get cdkVirtualForOf(): DataSource<T> | Observable<T[]> | NgIterable<T> | null | undefined {
8787
return this._cdkVirtualForOf;
8888
}
89-
set cdkVirtualForOf(value: DataSource<T> | Observable<T[]> | NgIterable<T>) {
89+
set cdkVirtualForOf(value: DataSource<T> | Observable<T[]> | NgIterable<T> | null | undefined) {
9090
this._cdkVirtualForOf = value;
9191
const ds = isDataSource(value) ? value :
9292
// Slice the value if its an NgIterable to ensure we're working with an array.
9393
new ArrayDataSource<T>(
9494
value instanceof Observable ? value : Array.prototype.slice.call(value || []));
9595
this._dataSourceChanges.next(ds);
9696
}
97-
_cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T>;
97+
_cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T> | null | undefined;
9898

9999
/**
100100
* The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and
@@ -363,7 +363,9 @@ export class CdkVirtualForOf<T> implements CollectionViewer, DoCheck, OnDestroy
363363
// comment node which can throw off the move when it's being repeated for all items.
364364
return this._viewContainerRef.createEmbeddedView(this._template, {
365365
$implicit: null!,
366-
cdkVirtualForOf: this._cdkVirtualForOf,
366+
// It's guaranteed that the iterable is not "undefined" or "null" because we only
367+
// generate views for elements if the "cdkVirtualForOf" iterable has elements.
368+
cdkVirtualForOf: this._cdkVirtualForOf!,
367369
index: -1,
368370
count: -1,
369371
first: false,

tools/public_api_guard/cdk/scrolling.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ export declare class CdkScrollable implements OnInit, OnDestroy {
6060
}
6161

6262
export declare class CdkVirtualForOf<T> implements CollectionViewer, DoCheck, OnDestroy {
63-
_cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T>;
64-
cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T>;
63+
_cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T> | null | undefined;
64+
cdkVirtualForOf: DataSource<T> | Observable<T[]> | NgIterable<T> | null | undefined;
6565
cdkVirtualForTemplate: TemplateRef<CdkVirtualForOfContext<T>>;
6666
cdkVirtualForTemplateCacheSize: number;
6767
cdkVirtualForTrackBy: TrackByFunction<T> | undefined;

0 commit comments

Comments
 (0)