Skip to content
Permalink
Browse files

feat(TS): Update to TypeScript 3.5.3

- 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
  • Loading branch information...
benlesh committed Aug 26, 2019
1 parent 8c32ed0 commit 741a136a341decf4361268e654388fc10abdb408

Large diffs are not rendered by default.

@@ -137,11 +137,11 @@
"check-side-effects": "0.0.20",
"color": "3.0.0",
"colors": "1.1.2",
"commitizen": "^3.1.1",
"commitizen": "^4.0.3",
"cross-env": "5.1.3",
"cz-conventional-changelog": "1.2.0",
"dependency-cruiser": "^4.17.0",
"dtslint": "0.7.4",
"dependency-cruiser": "^4.27.3",
"dtslint": "^0.7.4",
"escape-string-regexp": "1.0.5",
"eslint": "4.17.0",
"eslint-plugin-jasmine": "^2.10.1",
@@ -152,8 +152,8 @@
"google-closure-compiler-js": "20170218.0.0",
"gzip-size": "4.1.0",
"klaw-sync": "3.0.2",
"lint-staged": "^9.2.5",
"lodash": "^4.17.11",
"lint-staged": "^8.1.6",
"lodash": "^4.17.15",
"minimist": "1.2.0",
"mkdirp": "0.5.1",
"mocha": "5.0.0",
@@ -177,7 +177,7 @@
"tslint-etc": "1.5.0",
"tslint-no-toplevel-property-access": "0.0.2",
"tslint-no-unused-expression-chai": "0.0.3",
"typescript": "^3.0.1",
"typescript": "3.5.3",
"validate-commit-msg": "2.14.0",
"webpack": "^4.31.0"
},
@@ -74,8 +74,8 @@ describe('pipe', () => {
const o = of('foo').pipe(a('1'), a('2'), a('3'), a('4'), a('5'), a('6'), a('7'), a('8'), a('9')); // $ExpectType Observable<"9">
});

it('should infer {} for more than 9 arguments', () => {
const o = of('foo').pipe(a('1'), a('2'), a('3'), a('4'), a('5'), a('6'), a('7'), a('8'), a('9'), a('10')); // $ExpectType Observable<{}>
it('should infer unknown for more than 9 arguments', () => {
const o = of('foo').pipe(a('1'), a('2'), a('3'), a('4'), a('5'), a('6'), a('7'), a('8'), a('9'), a('10')); // $ExpectType Observable<unknown>
});

it('should require a type assertion for more than 9 arguments', () => {
@@ -119,7 +119,7 @@ describe('pipe', () => {
});

it('should not enforce types beyond the 9th argument', () => {
const o = of('foo').pipe(a('1'), a('2'), a('3'), a('4'), a('5'), a('6'), a('7'), a('8'), a('9'), a('#', '10')); // $ExpectType Observable<{}>
const o = of('foo').pipe(a('1'), a('2'), a('3'), a('4'), a('5'), a('6'), a('7'), a('8'), a('9'), a('#', '10')); // $ExpectType Observable<unknown>
});

it('should support operators that return generics', () => {
@@ -40,8 +40,8 @@ it('should accept 6 params', () => {
const o = combineLatest(a, b, c, d, e, f); // $ExpectType Observable<[A, B, C, D, E, F]>
});

it('should result in Observable<{}> for 7 or more params', () => {
const o = combineLatest(a, b, c, d, e, f, g); // $ExpectType Observable<{}>
it('should result in Observable<unknown> for 7 or more params', () => {
const o = combineLatest(a, b, c, d, e, f, g); // $ExpectType Observable<unknown>
});

it('should accept union types', () => {
@@ -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', () => {
const o = concat(of(1), of('a'), of(2), of(true), of(3), of([1, 2, 3]), of(4)); // $ExpectType Observable<unknown>
});

it('should accept scheduler after params', () => {
@@ -47,14 +47,14 @@ describe('race(a, b, c)', () => {
const o = race(a, a, a, a, a, a, a, a, a, a, a, a, a, a); // $ExpectType Observable<number>
});

it('should return {} for 6 or more arguments of different types', () => {
it('should return unknown for 6 or more arguments of different types', () => {
const a = of(1);
const b = of('a');
const c = of(true);
const d = of([1, 2, 3]);
const e = of(['blah']);
const f = of({ foo: 'bar' });
const o = race(a, b, c, d, e, f); // $ExpectType Observable<{}>
const o = race(a, b, c, d, e, f); // $ExpectType Observable<unknown>
});
});

@@ -107,7 +107,7 @@ describe('race([a, b, c])', () => {
const d = of([1, 2, 3]);
const e = of(['blah']);
const f = of({ foo: 'bar' });
const o = race([a, b, c, d, e, f]); // $ExpectType Observable<{}>
const o = race([a, b, c, d, e, f]); // $ExpectType Observable<unknown>
});
});

@@ -7,7 +7,7 @@ it('should infer correctly', () => {

it('should accept a keySelector', () => {
interface Person { name: string; }
const o = of<Person>({ name: 'Tim' }).pipe(distinct(person => person.name)); // $ExpectType Observable<Person>
const o = of({ name: 'Tim' } as Person).pipe(distinct(person => person.name)); // $ExpectType Observable<Person>
});

it('should accept flushes', () => {
@@ -55,5 +55,5 @@ it('should support inference from a return type with Boolean as a predicate', ()
}

const i$: Observable<I> = of();
const s$: Observable<string> = i$.pipe(map(i => i.a), filter(Boolean)); // $ExpectType Observable<string>
const s$ = i$.pipe(map(i => i.a), filter(Boolean)); // $ExpectType Observable<string>
});
@@ -43,7 +43,7 @@ it('should accept six inputs', () => {
});

it('should accept seven and more inputs', () => {
const o = of('apple', 'banana', 'peach').pipe(onErrorResumeNext(of(1), of(2), of('3'), of('4'), of(5), of('6'), of(7))); // $ExpectType Observable<string | {}>
const o = of('apple', 'banana', 'peach').pipe(onErrorResumeNext(of(1), of(2), of('3'), of('4'), of(5), of('6'), of(7))); // $ExpectType Observable<unknown>
const p = of('apple', 'banana', 'peach').pipe(onErrorResumeNext<string, string | number>(of(1), of(2), of('3'), of('4'), of(5), of('6'), of(7))); // $ExpectType Observable<string | number>
});

@@ -26,7 +26,7 @@ it('should support nested object of 6 layer depth', () => {
});

it('should support nested object of more than 6 layer depth', () => {
const a = of({ a: { b: { c: { d: { e: { f: { name: 'abc' } } } } } } }).pipe(pluck('a', 'b', 'c', 'd', 'e', 'f', 'name')); // $ExpectType Observable<{}>
const a = of({ a: { b: { c: { d: { e: { f: { name: 'abc' } } } } } } }).pipe(pluck('a', 'b', 'c', 'd', 'e', 'f', 'name')); // $ExpectType Observable<unknown>
});

it('should accept existing keys only', () => {
@@ -2,11 +2,7 @@ import { of, Observable } from 'rxjs';
import { publish } from 'rxjs/operators';

it('should support empty parameter', () => {
// Here, TypeScript versions 3.1 and earlier infer Observable<any>. However,
// the next version infers Observable<number>. It's not possible to specify
// an upper bound for the TypeScript version used by dtslint, so an
// expectation cannot be applied.
const a = of(1, 2, 3).pipe(publish()); // $ExpectType Observable<any>
const a = of(1, 2, 3).pipe(publish()); // $ExpectType Observable<number>
});

it('should infer when type is specified', () => {
@@ -2,11 +2,7 @@ import { of } from 'rxjs';
import { publishLast } from 'rxjs/operators';

it('should accept empty parameter', () => {
// Here, TypeScript versions 3.1 and earlier infer Observable<any>. However,
// the next version infers Observable<number>. It's not possible to specify
// an upper bound for the TypeScript version used by dtslint, so an
// expectation cannot be applied.
const a = of(1, 2, 3).pipe(publishLast()); // $ExpectType Observable<any>
const a = of(1, 2, 3).pipe(publishLast()); // $ExpectType Observable<number>
});

it('should infer when type is specified', () => {
@@ -31,9 +31,8 @@ it('should accept seed parameter of a different type', () => {
});

it('should act appropriately with no seed', () => {
// Because an observable of one value will just pass that value directly through the reducer,
// 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>
const b = of(1, 2, 3).pipe(reduce((a, v) => v)); // $ExpectType Observable<number>
const c = of(1, 2, 3).pipe(reduce(() => {})); // $ExpectType Observable<number | void>
});
@@ -31,9 +31,8 @@ it('should accept seed parameter of a different type', () => {
});

it('should act appropriately with no seed', () => {
// Because an observable of one value will just pass that value directly through the reducer,
// 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>
const b = of(1, 2, 3).pipe(scan((a, v) => v)); // $ExpectType Observable<number>
const c = of(1, 2, 3).pipe(scan(() => {})); // $ExpectType Observable<number | void>
});
@@ -51,7 +51,7 @@ describe('withLatestFrom', () => {
const e = of('j', 'k', 'l');
const f = of('m', 'n', 'o');
const g = of('p', 'q', 'r');
const res = a.pipe(withLatestFrom(b, c, d, e, f, g)); // $ExpectType Observable<{}>
const res = a.pipe(withLatestFrom(b, c, d, e, f, g)); // $ExpectType Observable<unknown>
});
});

@@ -4,7 +4,7 @@ import { zip } from 'rxjs/operators';
it('should support rest parameter observables', () => {
const o = of(1); // $ExpectType Observable<number>
const z = [of(2)]; // $ExpectType Observable<number>[]
const a = o.pipe(zip(...z)); // $ExpectType Observable<{}>
const a = o.pipe(zip(...z)); // $ExpectType Observable<unknown>
});

it('should support rest parameter observables with type parameters', () => {
@@ -21,8 +21,8 @@ function a<I extends string, O extends string>(input: I, output: O): UnaryFuncti
return i => output;
}

it('should infer {} for no arguments', () => {
const o = pipe(); // $ExpectType UnaryFunction<{}, {}>
it('should infer unknown for no arguments', () => {
const o = pipe(); // $ExpectType UnaryFunction<unknown, unknown>
});

it('should infer for 1 argument', () => {
@@ -115,12 +115,12 @@ it('should return an explicit Observable type', () => {
const o = of('foo').pipe(staticPipe); // $ExpectType Observable<string>
});

it('should return Observable<{}> when T cannot be inferred', () => {
it('should return Observable<unknown> when T cannot be inferred', () => {
const customOperator = <T>() => (a: Observable<T>) => a;

// type can't be possibly be inferred here, so it's {} instead of T.
// type can't be possibly be inferred here
const staticPipe = pipe(customOperator());
const o = of('foo').pipe(staticPipe); // $ExpectType Observable<{}>
const o = of('foo').pipe(staticPipe); // $ExpectType Observable<unknown>
});

it('should return a non-narrowed type', () => {
@@ -315,7 +315,7 @@ export class Observable<T> implements Subscribable<T> {
pipe<A, B, C, D, E, F, G>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>): Observable<G>;
pipe<A, B, C, D, E, F, G, H>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>): Observable<H>;
pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>): Observable<I>;
pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>, ...operations: OperatorFunction<any, any>[]): Observable<{}>;
pipe<A, B, C, D, E, F, G, H, I>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>, op4: OperatorFunction<C, D>, op5: OperatorFunction<D, E>, op6: OperatorFunction<E, F>, op7: OperatorFunction<F, G>, op8: OperatorFunction<G, H>, op9: OperatorFunction<H, I>, ...operations: OperatorFunction<any, any>[]): Observable<unknown>;
/* tslint:enable:max-line-length */

/**
@@ -16,7 +16,7 @@ export function race<A, B, C>(arg: [ObservableInput<A>, ObservableInput<B>, Obse
export function race<A, B, C, D>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>]): Observable<A | B | C | D>;
export function race<A, B, C, D, E>(arg: [ObservableInput<A>, ObservableInput<B>, ObservableInput<C>, ObservableInput<D>, ObservableInput<E>]): Observable<A | B | C | D | E>;
export function race<T>(arg: ObservableInput<T>[]): Observable<T>;
export function race(arg: ObservableInput<any>[]): Observable<{}>;
export function race(arg: ObservableInput<any>[]): Observable<unknown>;

export function race<A>(a: ObservableInput<A>): Observable<A>;
export function race<A, B>(a: ObservableInput<A>, b: ObservableInput<B>): Observable<A | B>;
@@ -26,9 +26,9 @@ export function race<A, B, C, D, E>(a: ObservableInput<A>, b: ObservableInput<B>
// tslint:enable:max-line-length

export function race<T>(observables: ObservableInput<T>[]): Observable<T>;
export function race(observables: ObservableInput<any>[]): Observable<{}>;
export function race(observables: ObservableInput<any>[]): Observable<unknown>;
export function race<T>(...observables: ObservableInput<T>[]): Observable<T>;
export function race(...observables: ObservableInput<any>[]): Observable<{}>;
export function race(...observables: ObservableInput<any>[]): Observable<unknown>;

/**
* Returns an Observable that mirrors the first source Observable to emit an item.

0 comments on commit 741a136

Please sign in to comment.
You can’t perform that action at this time.