From fce9aa12931796892673581761bba1f7ceafabff Mon Sep 17 00:00:00 2001 From: Ryan R Sundberg Date: Mon, 28 Mar 2022 06:25:14 -0700 Subject: [PATCH] fix: Now compatible with TypeScript 4.6 type checks (#6895) * 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 --- spec/ajax/index-spec.ts | 2 +- src/ajax/index.ts | 2 +- src/index.ts | 28 +++++++++++++-------- src/internal/Subscriber.ts | 2 +- src/internal/operators/groupBy.ts | 2 +- src/internal/operators/retry.ts | 2 +- src/internal/operators/shareReplay.ts | 2 +- src/internal/scheduler/immediateProvider.ts | 7 +++--- src/internal/scheduler/intervalProvider.ts | 9 ++++--- src/internal/scheduler/timeoutProvider.ts | 9 ++++--- src/internal/scheduler/timerHandle.ts | 1 + src/internal/testing/TestScheduler.ts | 11 ++++---- src/internal/util/workarounds.ts | 2 ++ src/operators/index.ts | 21 ++++++++++------ src/testing/index.ts | 3 ++- src/webSocket/index.ts | 3 ++- 16 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 src/internal/scheduler/timerHandle.ts diff --git a/spec/ajax/index-spec.ts b/spec/ajax/index-spec.ts index 0bb1b590d9..dac89ff958 100644 --- a/spec/ajax/index-spec.ts +++ b/spec/ajax/index-spec.ts @@ -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; }); }); diff --git a/src/ajax/index.ts b/src/ajax/index.ts index f30f026bc9..3e07b7bea0 100644 --- a/src/ajax/index.ts +++ b/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'; diff --git a/src/index.ts b/src/index.ts index 759b3103af..64183f8fcf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -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'; @@ -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'; @@ -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'; @@ -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'; @@ -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'; @@ -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'; diff --git a/src/internal/Subscriber.ts b/src/internal/Subscriber.ts index a09986d5c1..e682fe402b 100644 --- a/src/internal/Subscriber.ts +++ b/src/internal/Subscriber.ts @@ -203,7 +203,7 @@ export class SafeSubscriber extends Subscriber { // 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, }; diff --git a/src/internal/operators/groupBy.ts b/src/internal/operators/groupBy.ts index 33d5b23ddd..4e4d573f86 100644 --- a/src/internal/operators/groupBy.ts +++ b/src/internal/operators/groupBy.ts @@ -147,7 +147,7 @@ export function groupBy( 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); } diff --git a/src/internal/operators/retry.ts b/src/internal/operators/retry.ts index 74c5f5fc0b..ed04776b55 100644 --- a/src/internal/operators/retry.ts +++ b/src/internal/operators/retry.ts @@ -86,7 +86,7 @@ export function retry(configOrCount: number | RetryConfig = Infinity): MonoTy config = configOrCount; } else { config = { - count: configOrCount, + count: configOrCount as number, }; } const { count = Infinity, delay, resetOnSuccess: resetOnSuccess = false } = config; diff --git a/src/internal/operators/shareReplay.ts b/src/internal/operators/shareReplay.ts index 095c7df111..28149a6568 100644 --- a/src/internal/operators/shareReplay.ts +++ b/src/internal/operators/shareReplay.ts @@ -161,7 +161,7 @@ export function shareReplay( if (configOrBufferSize && typeof configOrBufferSize === 'object') { ({ bufferSize = Infinity, windowTime = Infinity, refCount = false, scheduler } = configOrBufferSize); } else { - bufferSize = configOrBufferSize ?? Infinity; + bufferSize = (configOrBufferSize ?? Infinity) as number; } return share({ connector: () => new ReplaySubject(bufferSize, windowTime, scheduler), diff --git a/src/internal/scheduler/immediateProvider.ts b/src/internal/scheduler/immediateProvider.ts index 7919c48ecd..d70fbf3295 100644 --- a/src/internal/scheduler/immediateProvider.ts +++ b/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; @@ -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, }; diff --git a/src/internal/scheduler/intervalProvider.ts b/src/internal/scheduler/intervalProvider.ts index dc64c7c91f..032317d682 100644 --- a/src/internal/scheduler/intervalProvider.ts +++ b/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; @@ -16,7 +17,7 @@ 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); } @@ -24,7 +25,7 @@ export const intervalProvider: IntervalProvider = { }, clearInterval(handle) { const { delegate } = intervalProvider; - return (delegate?.clearInterval || clearInterval)(handle); + return (delegate?.clearInterval || clearInterval)(handle as any); }, delegate: undefined, }; diff --git a/src/internal/scheduler/timeoutProvider.ts b/src/internal/scheduler/timeoutProvider.ts index 8cee7673e2..205e0163a5 100644 --- a/src/internal/scheduler/timeoutProvider.ts +++ b/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; @@ -16,7 +17,7 @@ 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); } @@ -24,7 +25,7 @@ export const timeoutProvider: TimeoutProvider = { }, clearTimeout(handle) { const { delegate } = timeoutProvider; - return (delegate?.clearTimeout || clearTimeout)(handle); + return (delegate?.clearTimeout || clearTimeout)(handle as any); }, delegate: undefined, }; diff --git a/src/internal/scheduler/timerHandle.ts b/src/internal/scheduler/timerHandle.ts new file mode 100644 index 0000000000..0b0416486c --- /dev/null +++ b/src/internal/scheduler/timerHandle.ts @@ -0,0 +1 @@ +export type TimerHandle = number | NodeJS.Timeout; diff --git a/src/internal/testing/TestScheduler.ts b/src/internal/testing/TestScheduler.ts index e08fd180b6..88fd70bba5 100644 --- a/src/internal/testing/TestScheduler.ts +++ b/src/internal/testing/TestScheduler.ts @@ -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'; @@ -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'; @@ -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(); @@ -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(); @@ -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(); diff --git a/src/internal/util/workarounds.ts b/src/internal/util/workarounds.ts index 7a2ae54b93..00c01b881a 100644 --- a/src/internal/util/workarounds.ts +++ b/src/internal/util/workarounds.ts @@ -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 {} diff --git a/src/operators/index.ts b/src/operators/index.ts index 9272c89780..b7da7cb879 100644 --- a/src/operators/index.ts +++ b/src/operators/index.ts @@ -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'; @@ -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'; @@ -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'; @@ -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'; diff --git a/src/testing/index.ts b/src/testing/index.ts index d861e3513a..7908dc82af 100644 --- a/src/testing/index.ts +++ b/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'; diff --git a/src/webSocket/index.ts b/src/webSocket/index.ts index 833d950479..6665d28dd4 100644 --- a/src/webSocket/index.ts +++ b/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';