Rxjs: startWith Deprecation warning

Created on 11 May 2019  路  16Comments  路  Source: ReactiveX/rxjs

I can't find any documentation on what is actually deprecated, but I believe this is related to: https://github.com/ReactiveX/rxjs/issues/4723.

Bug Report

Current Behavior
startWith is deprecated: use {@link scheduled} and {@link concatAll} (e.g. scheduled([[a, b, c], source], schedul er).pipe(concatAll()))

Reproduction

startWith(null);

Expected behavior
No deprecation warning

Environment

  • RxJS version: 6.5.2

Most helpful comment

The deprecation warning also disappears when typing the null in startWith.
By default it's typed any, so I guess the compiler doesn't know it's not meant to be a SchedulerLike.

startWith(<string>null); // In case your stream emits strings

All 16 comments

The problem is related to the issue you referenced only in that some operators and observable creators that have signatures that include a Scheduler parameter have those signatures deprecated.

In your case, startWith(null) is matching this signature:

export function startWith<T>(scheduler: SchedulerLike): MonoTypeOperatorFunction<T>;

And it only matches that signature because you most likely have "strictNullChecks": false in your TypeScript configuration - either explicitly or implicitly.

Given that this is not a problem for in situations in which strictNullChecks are enabled, IMO, the deprecation should be left in place and a TSLint flag should be used to suppress the warning:

// tslint:disable-next-line:deprecation
startWith(null)

Do you mean in tslint.json? I don't see that setting but I will try adding it and see if it makes a difference. The warning fires for undefined aswell as null too.

The comment I mentioned is a rule flag and goes into the source - immediately above the line that effects the error.

Or you can configure the deprecation rule to be either off or a warning in the tslint.json file:

"deprecation": { "severity": "warning" },

Without strictNullChecks enabled, both undefined and null will match the Scheduler parameter in the deprecated signature. Enabling strictNullChecks is recommended, IMO.

I wish I'd known about strictNullChecks when we started this application ... Unfortunately this is not an easy switch for us and thus I won't be able to confirm whether this resolves the problem for some time. I'm happy to delegate that to someone else with the same problem.

@internalsystemerror Regarding enabling strictNullChecks, you might find this relevant/interesting/helpful: https://code.visualstudio.com/blogs/2019/05/23/strict-null

@cartant thank you ... its the part "(I will add that if you are starting a new TypeScript project, do your future self a favour and start with "strict": true as the default.)" that I wish I'd have known :D. Definitely going to be using that going forward and retrospectively on this current application when possible.

The deprecation warning also disappears when typing the null in startWith.
By default it's typed any, so I guess the compiler doesn't know it's not meant to be a SchedulerLike.

startWith(<string>null); // In case your stream emits strings

@cartant, I haven't checked... is this something we can remedy by changing the order of typings for startWith?

@benlesh I don't see how it could be rearranged without changing the behaviour of the types. ATM, a lone scheduler argument is seen as a scheduler. If the order is changed, it will be seen as a value - as far as the type system is concerned. Admittedly, this is a pretty unlikely use case, but the signature that's causing the problem is there because it's behaviour supported by the implementation.

If you want to fix the 90% case - that is, fixed for at least 90% of the people not using strictNullChecks - removing the signature that takes a scheduler as a single argument is probably the best that can be done.

Coming from Angular, I run into it when using a pattern like

this.myFormControl.valueChanges.pipe(
    startWith(this.myFormControl.value)
  )

since FormControls are typed as any. I suspect that the false positive with any is more common than actually using the deprecated single-argument scheduler, so I'll cast a vote for removing the signature.

For me, I hit this and read this thread, and found that typeing the reference made the issue go away without any further problems.

    this.activities = this.activityListForm.valueChanges.pipe(
      debounceTime(500),
      startWith(this.activityListForm.value as object),
      switchMap(formFilter => this.activityService.list(formFilter, this.pageSize)),
      share()
    );
startWith(null as string)

Here's another hacky fix:

const nullValue = null;
startWith(nullValue);

No hacks (obfuscating) or cheats (tslint:disable comments) please. Also null is not a string. (no cast). What's the problem if I expect (and my type is set to) optionally null? e.g. An array which could contain null values. But the deprecated error on using startWith(null) will not disappear if I change my type to fit it. Also when the type is any.
Why exactly is it marked as deprecated and what's the problem? In simple words and examples.

My current alternative for a specific case (text input element) is to use an empty string ''. It's also a falsy value. startWith(''). But the observable event is from type any. So null should also accepted.
(Background: I use Angular Material "FormControl" valueChanges.)

I have "strictNullChecks": true in tsconfig.json and I'm still getting this error when using startWith(null)

startWith(blah)

Was this page helpful?
0 / 5 - 0 ratings