Skip to content

Commit

Permalink
fix: Now compatible with TypeScript 4.6 type checks (#6895)
Browse files Browse the repository at this point in the history
* fix(typescript): type check failures in typescript 4.6

* fix(timers): TimerHandle type to resolve node/browser timer handle types

setInterval/setTimeout/setImmediate have different return types in
node.js and the browser. Define TimerHandle to abstract the difference
and fix compilation errors where the return type was a number.

* Use `export type` for re-exporting type definitions

Fixes compilation under typescript with `isolatedModules: true`

See https://devblogs.microsoft.com/typescript/announcing-typescript-3-8/#type-only-imports-exports
  • Loading branch information
sundbry committed Mar 28, 2022
1 parent 708c0a7 commit fce9aa1
Show file tree
Hide file tree
Showing 16 changed files with 65 additions and 41 deletions.
2 changes: 1 addition & 1 deletion spec/ajax/index-spec.ts
Expand Up @@ -7,10 +7,10 @@ describe('index', () => {
});

it('should export Ajax data classes', () => {
expect(index.AjaxResponse).to.exist;
expect(index.AjaxError).to.exist;
expect(index.AjaxTimeoutError).to.exist;
// Interfaces can be checked by creating a variable of that type
let ajaxRequest: index.AjaxRequest;
let ajaxResponse: index.AjaxResponse<object>;
});
});
2 changes: 1 addition & 1 deletion src/ajax/index.ts
@@ -1,4 +1,4 @@
export { ajax } from '../internal/ajax/ajax';
export { AjaxError, AjaxTimeoutError } from '../internal/ajax/errors';
export { AjaxResponse } from '../internal/ajax/AjaxResponse';
export { AjaxRequest, AjaxConfig, AjaxDirection } from '../internal/ajax/types';
export type { AjaxRequest, AjaxConfig, AjaxDirection } from '../internal/ajax/types';
28 changes: 18 additions & 10 deletions src/index.ts
Expand Up @@ -15,8 +15,8 @@
/* Observable */
export { Observable } from './internal/Observable';
export { ConnectableObservable } from './internal/observable/ConnectableObservable';
export { GroupedObservable } from './internal/operators/groupBy';
export { Operator } from './internal/Operator';
export type { GroupedObservable } from './internal/operators/groupBy';
export type { Operator } from './internal/Operator';
export { observable } from './internal/symbol/observable';
export { animationFrames } from './internal/observable/dom/animationFrames';

Expand Down Expand Up @@ -97,7 +97,8 @@ export { NEVER } from './internal/observable/never';
export * from './internal/types';

/* Config */
export { config, GlobalConfig } from './internal/config';
export { config } from './internal/config';
export type { GlobalConfig } from './internal/config';

/* Operators */
export { audit } from './internal/operators/audit';
Expand All @@ -115,7 +116,8 @@ export { concatAll } from './internal/operators/concatAll';
export { concatMap } from './internal/operators/concatMap';
export { concatMapTo } from './internal/operators/concatMapTo';
export { concatWith } from './internal/operators/concatWith';
export { connect, ConnectConfig } from './internal/operators/connect';
export { connect } from './internal/operators/connect';
export type { ConnectConfig } from './internal/operators/connect';
export { count } from './internal/operators/count';
export { debounce } from './internal/operators/debounce';
export { debounceTime } from './internal/operators/debounceTime';
Expand All @@ -138,7 +140,8 @@ export { finalize } from './internal/operators/finalize';
export { find } from './internal/operators/find';
export { findIndex } from './internal/operators/findIndex';
export { first } from './internal/operators/first';
export { groupBy, BasicGroupByOptions, GroupByOptionsWithElement } from './internal/operators/groupBy';
export { groupBy } from './internal/operators/groupBy';
export type { BasicGroupByOptions, GroupByOptionsWithElement } from './internal/operators/groupBy';
export { ignoreElements } from './internal/operators/ignoreElements';
export { isEmpty } from './internal/operators/isEmpty';
export { last } from './internal/operators/last';
Expand All @@ -165,15 +168,18 @@ export { raceWith } from './internal/operators/raceWith';
export { reduce } from './internal/operators/reduce';
export { repeat } from './internal/operators/repeat';
export { repeatWhen } from './internal/operators/repeatWhen';
export { retry, RetryConfig } from './internal/operators/retry';
export { retry } from './internal/operators/retry';
export type { RetryConfig } from './internal/operators/retry';
export { retryWhen } from './internal/operators/retryWhen';
export { refCount } from './internal/operators/refCount';
export { sample } from './internal/operators/sample';
export { sampleTime } from './internal/operators/sampleTime';
export { scan } from './internal/operators/scan';
export { sequenceEqual } from './internal/operators/sequenceEqual';
export { share, ShareConfig } from './internal/operators/share';
export { shareReplay, ShareReplayConfig } from './internal/operators/shareReplay';
export { share } from './internal/operators/share';
export type { ShareConfig } from './internal/operators/share';
export { shareReplay } from './internal/operators/shareReplay';
export type { ShareReplayConfig } from './internal/operators/shareReplay';
export { single } from './internal/operators/single';
export { skip } from './internal/operators/skip';
export { skipLast } from './internal/operators/skipLast';
Expand All @@ -190,11 +196,13 @@ export { takeLast } from './internal/operators/takeLast';
export { takeUntil } from './internal/operators/takeUntil';
export { takeWhile } from './internal/operators/takeWhile';
export { tap } from './internal/operators/tap';
export { throttle, ThrottleConfig } from './internal/operators/throttle';
export { throttle } from './internal/operators/throttle';
export type { ThrottleConfig } from './internal/operators/throttle';
export { throttleTime } from './internal/operators/throttleTime';
export { throwIfEmpty } from './internal/operators/throwIfEmpty';
export { timeInterval } from './internal/operators/timeInterval';
export { timeout, TimeoutConfig, TimeoutInfo } from './internal/operators/timeout';
export { timeout } from './internal/operators/timeout';
export type { TimeoutConfig, TimeoutInfo } from './internal/operators/timeout';
export { timeoutWith } from './internal/operators/timeoutWith';
export { timestamp } from './internal/operators/timestamp';
export { toArray } from './internal/operators/toArray';
Expand Down
2 changes: 1 addition & 1 deletion src/internal/Subscriber.ts
Expand Up @@ -203,7 +203,7 @@ export class SafeSubscriber<T> extends Subscriber<T> {
// The first argument is a function, not an observer. The next
// two arguments *could* be observers, or they could be empty.
partialObserver = {
next: observerOrNext ?? undefined,
next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),
error: error ?? undefined,
complete: complete ?? undefined,
};
Expand Down
2 changes: 1 addition & 1 deletion src/internal/operators/groupBy.ts
Expand Up @@ -147,7 +147,7 @@ export function groupBy<T, K, R>(
return operate((source, subscriber) => {
let element: ((value: any) => any) | void;
if (!elementOrOptions || typeof elementOrOptions === 'function') {
element = elementOrOptions;
element = elementOrOptions as ((value: any) => any);
} else {
({ duration, element, connector } = elementOrOptions);
}
Expand Down
2 changes: 1 addition & 1 deletion src/internal/operators/retry.ts
Expand Up @@ -86,7 +86,7 @@ export function retry<T>(configOrCount: number | RetryConfig = Infinity): MonoTy
config = configOrCount;
} else {
config = {
count: configOrCount,
count: configOrCount as number,
};
}
const { count = Infinity, delay, resetOnSuccess: resetOnSuccess = false } = config;
Expand Down
2 changes: 1 addition & 1 deletion src/internal/operators/shareReplay.ts
Expand Up @@ -161,7 +161,7 @@ export function shareReplay<T>(
if (configOrBufferSize && typeof configOrBufferSize === 'object') {
({ bufferSize = Infinity, windowTime = Infinity, refCount = false, scheduler } = configOrBufferSize);
} else {
bufferSize = configOrBufferSize ?? Infinity;
bufferSize = (configOrBufferSize ?? Infinity) as number;
}
return share<T>({
connector: () => new ReplaySubject(bufferSize, windowTime, scheduler),
Expand Down
7 changes: 4 additions & 3 deletions src/internal/scheduler/immediateProvider.ts
@@ -1,8 +1,9 @@
import { Immediate } from '../util/Immediate';
import type { TimerHandle } from './timerHandle';
const { setImmediate, clearImmediate } = Immediate;

type SetImmediateFunction = (handler: () => void, ...args: any[]) => number;
type ClearImmediateFunction = (handle: number) => void;
type SetImmediateFunction = (handler: () => void, ...args: any[]) => TimerHandle;
type ClearImmediateFunction = (handle: TimerHandle) => void;

interface ImmediateProvider {
setImmediate: SetImmediateFunction;
Expand All @@ -24,7 +25,7 @@ export const immediateProvider: ImmediateProvider = {
},
clearImmediate(handle) {
const { delegate } = immediateProvider;
return (delegate?.clearImmediate || clearImmediate)(handle);
return (delegate?.clearImmediate || clearImmediate)(handle as any);
},
delegate: undefined,
};
9 changes: 5 additions & 4 deletions src/internal/scheduler/intervalProvider.ts
@@ -1,5 +1,6 @@
type SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => number;
type ClearIntervalFunction = (handle: number) => void;
import type { TimerHandle } from './timerHandle';
type SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;
type ClearIntervalFunction = (handle: TimerHandle) => void;

interface IntervalProvider {
setInterval: SetIntervalFunction;
Expand All @@ -16,15 +17,15 @@ export const intervalProvider: IntervalProvider = {
// When accessing the delegate, use the variable rather than `this` so that
// the functions can be called without being bound to the provider.
setInterval(handler: () => void, timeout?: number, ...args) {
const {delegate} = intervalProvider;
const { delegate } = intervalProvider;
if (delegate?.setInterval) {
return delegate.setInterval(handler, timeout, ...args);
}
return setInterval(handler, timeout, ...args);
},
clearInterval(handle) {
const { delegate } = intervalProvider;
return (delegate?.clearInterval || clearInterval)(handle);
return (delegate?.clearInterval || clearInterval)(handle as any);
},
delegate: undefined,
};
9 changes: 5 additions & 4 deletions src/internal/scheduler/timeoutProvider.ts
@@ -1,5 +1,6 @@
type SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => number;
type ClearTimeoutFunction = (handle: number) => void;
import type { TimerHandle } from './timerHandle';
type SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;
type ClearTimeoutFunction = (handle: TimerHandle) => void;

interface TimeoutProvider {
setTimeout: SetTimeoutFunction;
Expand All @@ -16,15 +17,15 @@ export const timeoutProvider: TimeoutProvider = {
// When accessing the delegate, use the variable rather than `this` so that
// the functions can be called without being bound to the provider.
setTimeout(handler: () => void, timeout?: number, ...args) {
const {delegate} = timeoutProvider;
const { delegate } = timeoutProvider;
if (delegate?.setTimeout) {
return delegate.setTimeout(handler, timeout, ...args);
}
return setTimeout(handler, timeout, ...args);
},
clearTimeout(handle) {
const { delegate } = timeoutProvider;
return (delegate?.clearTimeout || clearTimeout)(handle);
return (delegate?.clearTimeout || clearTimeout)(handle as any);
},
delegate: undefined,
};
1 change: 1 addition & 0 deletions src/internal/scheduler/timerHandle.ts
@@ -0,0 +1 @@
export type TimerHandle = number | NodeJS.Timeout;
11 changes: 6 additions & 5 deletions src/internal/testing/TestScheduler.ts
Expand Up @@ -10,6 +10,7 @@ import { COMPLETE_NOTIFICATION, errorNotification, nextNotification } from '../N
import { dateTimestampProvider } from '../scheduler/dateTimestampProvider';
import { performanceTimestampProvider } from '../scheduler/performanceTimestampProvider';
import { animationFrameProvider } from '../scheduler/animationFrameProvider';
import type { TimerHandle } from '../scheduler/timerHandle';
import { immediateProvider } from '../scheduler/immediateProvider';
import { intervalProvider } from '../scheduler/intervalProvider';
import { timeoutProvider } from '../scheduler/timeoutProvider';
Expand Down Expand Up @@ -510,11 +511,11 @@ export class TestScheduler extends VirtualTimeScheduler {

let lastHandle = 0;
const scheduleLookup = new Map<
number,
TimerHandle,
{
due: number;
duration: number;
handle: number;
handle: TimerHandle;
handler: () => void;
subscription: Subscription;
type: 'immediate' | 'interval' | 'timeout';
Expand Down Expand Up @@ -582,7 +583,7 @@ export class TestScheduler extends VirtualTimeScheduler {
});
return handle;
},
clearImmediate: (handle: number) => {
clearImmediate: (handle: TimerHandle) => {
const value = scheduleLookup.get(handle);
if (value) {
value.subscription.unsubscribe();
Expand All @@ -604,7 +605,7 @@ export class TestScheduler extends VirtualTimeScheduler {
});
return handle;
},
clearInterval: (handle: number) => {
clearInterval: (handle: TimerHandle) => {
const value = scheduleLookup.get(handle);
if (value) {
value.subscription.unsubscribe();
Expand All @@ -626,7 +627,7 @@ export class TestScheduler extends VirtualTimeScheduler {
});
return handle;
},
clearTimeout: (handle: number) => {
clearTimeout: (handle: TimerHandle) => {
const value = scheduleLookup.get(handle);
if (value) {
value.subscription.unsubscribe();
Expand Down
2 changes: 2 additions & 0 deletions src/internal/util/workarounds.ts
Expand Up @@ -3,3 +3,5 @@
// Wherever possible, use a TypeScript issue number in the type - something
// like TS_18757 - or use a descriptive name and leave a detailed comment
// alongside the type alias.

export {}
21 changes: 14 additions & 7 deletions src/operators/index.ts
Expand Up @@ -16,7 +16,8 @@ export { concatAll } from '../internal/operators/concatAll';
export { concatMap } from '../internal/operators/concatMap';
export { concatMapTo } from '../internal/operators/concatMapTo';
export { concatWith } from '../internal/operators/concatWith';
export { connect, ConnectConfig } from '../internal/operators/connect';
export { connect } from '../internal/operators/connect';
export type { ConnectConfig } from '../internal/operators/connect';
export { count } from '../internal/operators/count';
export { debounce } from '../internal/operators/debounce';
export { debounceTime } from '../internal/operators/debounceTime';
Expand All @@ -39,7 +40,8 @@ export { finalize } from '../internal/operators/finalize';
export { find } from '../internal/operators/find';
export { findIndex } from '../internal/operators/findIndex';
export { first } from '../internal/operators/first';
export { groupBy, BasicGroupByOptions, GroupByOptionsWithElement } from '../internal/operators/groupBy';
export { groupBy } from '../internal/operators/groupBy';
export type { BasicGroupByOptions, GroupByOptionsWithElement } from '../internal/operators/groupBy';
export { ignoreElements } from '../internal/operators/ignoreElements';
export { isEmpty } from '../internal/operators/isEmpty';
export { last } from '../internal/operators/last';
Expand Down Expand Up @@ -70,15 +72,18 @@ export { raceWith } from '../internal/operators/raceWith';
export { reduce } from '../internal/operators/reduce';
export { repeat } from '../internal/operators/repeat';
export { repeatWhen } from '../internal/operators/repeatWhen';
export { retry, RetryConfig } from '../internal/operators/retry';
export { retry } from '../internal/operators/retry';
export type { RetryConfig } from '../internal/operators/retry';
export { retryWhen } from '../internal/operators/retryWhen';
export { refCount } from '../internal/operators/refCount';
export { sample } from '../internal/operators/sample';
export { sampleTime } from '../internal/operators/sampleTime';
export { scan } from '../internal/operators/scan';
export { sequenceEqual } from '../internal/operators/sequenceEqual';
export { share, ShareConfig } from '../internal/operators/share';
export { shareReplay, ShareReplayConfig } from '../internal/operators/shareReplay';
export { share } from '../internal/operators/share';
export type { ShareConfig } from '../internal/operators/share';
export { shareReplay } from '../internal/operators/shareReplay';
export type { ShareReplayConfig } from '../internal/operators/shareReplay';
export { single } from '../internal/operators/single';
export { skip } from '../internal/operators/skip';
export { skipLast } from '../internal/operators/skipLast';
Expand All @@ -95,11 +100,13 @@ export { takeLast } from '../internal/operators/takeLast';
export { takeUntil } from '../internal/operators/takeUntil';
export { takeWhile } from '../internal/operators/takeWhile';
export { tap } from '../internal/operators/tap';
export { throttle, ThrottleConfig } from '../internal/operators/throttle';
export { throttle } from '../internal/operators/throttle';
export type { ThrottleConfig } from '../internal/operators/throttle';
export { throttleTime } from '../internal/operators/throttleTime';
export { throwIfEmpty } from '../internal/operators/throwIfEmpty';
export { timeInterval } from '../internal/operators/timeInterval';
export { timeout, TimeoutConfig, TimeoutInfo } from '../internal/operators/timeout';
export { timeout } from '../internal/operators/timeout';
export type { TimeoutConfig, TimeoutInfo } from '../internal/operators/timeout';
export { timeoutWith } from '../internal/operators/timeoutWith';
export { timestamp } from '../internal/operators/timestamp';
export { toArray } from '../internal/operators/toArray';
Expand Down
3 changes: 2 additions & 1 deletion src/testing/index.ts
@@ -1 +1,2 @@
export { TestScheduler, RunHelpers } from '../internal/testing/TestScheduler';
export { TestScheduler } from '../internal/testing/TestScheduler';
export type { RunHelpers } from '../internal/testing/TestScheduler';
3 changes: 2 additions & 1 deletion src/webSocket/index.ts
@@ -1,2 +1,3 @@
export { webSocket as webSocket } from '../internal/observable/dom/webSocket';
export { WebSocketSubject, WebSocketSubjectConfig } from '../internal/observable/dom/WebSocketSubject';
export { WebSocketSubject } from '../internal/observable/dom/WebSocketSubject';
export type { WebSocketSubjectConfig } from '../internal/observable/dom/WebSocketSubject';

0 comments on commit fce9aa1

Please sign in to comment.