Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to TypeScript 3.5.3 #4985

Merged
merged 10 commits into from
Sep 16, 2019
Merged

Update to TypeScript 3.5.3 #4985

merged 10 commits into from
Sep 16, 2019

Conversation

benlesh
Copy link
Member

@benlesh benlesh commented Aug 27, 2019

  • Updates places that were inferring Observable<{}> to infer Observable<unknown> instead.
  • Updates to proper types for TS 3.5.3 for certain dtslint tests
  • Updates types for of.
    • BREAKING CHANGE: generic signature of of has changed. Users should allow this type to infer properly or use as. There is deprecated handling for the common cases of of<T>() and of<T>(x), but multiple specified generic arguments (like of<A, B>(a, b)) will yield incorrect types, possibly build errors, and should not be used.
    • BREAKING CHANGE: uses of of with >9 arguments punctuated with a SchedulerLike will no longer properly infer, and will need to be cast. Scheduled of is deprecated anyhow, and developers should be using scheduled from rxjs. (Before it would infer Observable<{}>, which is no longer possible, and now it will infer Observable<A | B | C | D | E | F | G | H | I>, which isn't correct. Again, use scheduled instead.

@benlesh
Copy link
Member Author

benlesh commented Aug 27, 2019

Replaces #4976

Copy link
Collaborator

@cartant cartant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Just a couple of nits/questions.

@@ -101,3 +101,5 @@ export interface SchedulerAction<T> extends Subscription {
export type ObservedValueOf<O> = O extends ObservableInput<infer T> ? T : never;

export type ObservedValuesFromArray<X> = X extends Array<ObservableInput<infer T>> ? T : never;

export type ArrayValueOf<A> = A extends Array<infer T> ? T : never;
Copy link
Collaborator

@cartant cartant Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that the type above this one is named ObservedValuesFromArray and extracts the observed values from an array and that this one just extracts the value from an array, should it be called ValueFromArray?

@@ -139,5 +139,5 @@ export function concat<R>(...observables: (ObservableInput<any> | SchedulerLike)
* @owner Observable
*/
export function concat<O extends ObservableInput<any>, R>(...observables: Array<O | SchedulerLike>): Observable<ObservedValueOf<O> | R> {
Copy link
Collaborator

@cartant cartant Aug 27, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this R here and in the signatures above it? It seems that it's only present so that folk can explicitly provide it as a type parameter and do we really want to encourage that? IIRC, when discussing this sort of thing with Rado, the preference was to return Observable<unknown> - or, at the time, Observable<{}> - and require the caller to use an as assertion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking at that and thought the same thing, honestly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I updated the typings for concat. Note the possible breaking change for people that are explicitly passing generics.

// the below could be a number or a string.
const a = of(1, 2, 3).pipe(scan((a: any, v) => '' + v)); // $ExpectType Observable<string | number>
// Starting in TS 3.5, the return type is inferred from the accumulator's type if it's provided without a seed.
const a = of(1, 2, 3).pipe(scan((a: any, v) => '' + v)); // $ExpectType Observable<any>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe type the accumulator as a string and expect Observable<string>? Is there anything to be gained by using any here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is if you do a: string, TypeScript will infer an operator like OperatorFunction<string, string>, which is incorrect here, with a source of Observable<number>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Do you think it would be worth including another test that explicitly types the value - to make sure that works, too? I assume that value will also be any here - for the reason you gave above? FWIW, in application code I'd type it like this:

(scan((a: string, v: number) => '' + v))

So maybe we need a test to make sure this is okay?

// the below could be a number or a string.
const a = of(1, 2, 3).pipe(reduce((a: any, v) => '' + v)); // $ExpectType Observable<string | number>
// Starting in TS 3.5, the return type is inferred from the accumulator's type if it's provided without a seed.
const a = of(1, 2, 3).pipe(reduce((a: any, v) => '' + v)); // $ExpectType Observable<any>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for scan, maybe use string as the accumulator type?

Copy link
Collaborator

@cartant cartant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. A nit about a test description and an unused import, that's all.

@@ -28,8 +28,8 @@ it('should accept more than 6 params', () => {
const o = concat(of(1), of(2), of(3), of(4), of(5), of(6), of(7), of(8), of(9)); // $ExpectType Observable<number>
});

it('should return Observable<{}> for more than 6 different types of params', () => {
const o = concat(of(1), of('a'), of(2), of(true), of(3), of([1, 2, 3]), of(4)); // $ExpectType Observable<{}>
it('should return Observable<unknown> for more than 6 different types of params', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description no longer matches the test's expectation.

import { isScheduler } from '../util/isScheduler';
import { fromArray } from './fromArray';
import { Observable } from '../Observable';
import { scheduleArray } from '../scheduled/scheduleArray';
import { never } from './never';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't needed. It looks like VS Code's auto-import has added this.

- Uses `unknown` type instead of `{}` per TS 3
- Updates dtslint tests where certain things are now working better

BREAKING CHANGE: RxJS requires TS 3.5
- `of()` now properly infers `Observable<never>`
- `of()` can handle any number of arguments gracefully

BREAKING CHANGE: Generic signature changed, do not specify generics, allow them to be inferred or use `as`
BREAKING CHANGE: Use with more than 9 arguments, where the last argument is a `SchedulerLike` may result in the wrong type which includes the `SchedulerLike`, even though the run time implementation does not support that. Developers should be using `scheduled` instead
- Removes superfluous return typing
- Updates deprecation messages

BREAKING CHANGE: `concat` generic signature changed. Recommend not explicitly passing generics, just let inference do its job. If you must, cast with `as`.
Updates bad types in test-helpers and removes dependency on symbol-observable
@benlesh benlesh merged commit 56cbd22 into ReactiveX:master Sep 16, 2019
@benlesh benlesh deleted the update-ts-3.5.3 branch September 16, 2019 19:49
@lock lock bot locked as resolved and limited conversation to collaborators Oct 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants