Skip to content

Commit 05e8383

Browse files
Merge pull request #157 from MattiasBuelens/improve-abortsignal-type
Improve type of `WritableStreamDefaultController.signal`
2 parents c2f7590 + 82f3bb2 commit 05e8383

13 files changed

+45
-56
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
* The `next()` and `return()` methods of `ReadableStream`'s async iterator are now correctly "chained",
2020
such that the promises returned by *either* of these methods are always resolved in the same order
2121
as those methods were called.
22+
* 💅 Improve type of `WritableStreamDefaultController.signal`. ([#157](https://github.com/MattiasBuelens/web-streams-polyfill/pull/157))
2223

2324
## 4.0.0 (2024-02-28)
2425

etc/web-streams-polyfill.api.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
```ts
66

77
// @public
8-
export interface AbortSignal {
9-
readonly aborted: boolean;
10-
addEventListener(type: 'abort', listener: () => void): void;
8+
export type AbortSignal = typeof globalThis extends {
9+
AbortSignal: {
10+
prototype: infer T;
11+
};
12+
} ? T : {
13+
aborted: boolean;
1114
readonly reason?: any;
15+
addEventListener(type: 'abort', listener: () => void): void;
1216
removeEventListener(type: 'abort', listener: () => void): void;
13-
}
17+
};
1418

1519
// @public
1620
export class ByteLengthQueuingStrategy implements QueuingStrategy<ArrayBufferView> {

src/globals.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
/// <reference lib="dom" />
22

3+
declare global {
4+
// From @types/node
5+
// eslint-disable-next-line no-var
6+
var global: typeof globalThis;
7+
}
8+
39
function getGlobals(): typeof globalThis | undefined {
410
if (typeof globalThis !== 'undefined') {
511
return globalThis;

src/lib/abort-signal.ts

Lines changed: 11 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,16 @@
33
* via its associated `AbortController` object.
44
*
55
* @remarks
6-
* This interface is compatible with the `AbortSignal` interface defined in TypeScript's DOM types.
7-
* It is redefined here, so it can be polyfilled without a DOM, for example with
8-
* {@link https://www.npmjs.com/package/abortcontroller-polyfill | abortcontroller-polyfill} in a Node environment.
6+
* This is equivalent to the `AbortSignal` interface defined in TypeScript's DOM types or `@types/node`.
97
*
108
* @public
119
*/
12-
export interface AbortSignal {
13-
/**
14-
* Whether the request is aborted.
15-
*/
16-
readonly aborted: boolean;
17-
18-
/**
19-
* If aborted, returns the reason for aborting.
20-
*/
10+
export type AbortSignal = typeof globalThis extends { AbortSignal: { prototype: infer T } } ? T : {
11+
aborted: boolean;
2112
readonly reason?: any;
22-
23-
/**
24-
* Add an event listener to be triggered when this signal becomes aborted.
25-
*/
2613
addEventListener(type: 'abort', listener: () => void): void;
27-
28-
/**
29-
* Remove an event listener that was previously added with {@link AbortSignal.addEventListener}.
30-
*/
3114
removeEventListener(type: 'abort', listener: () => void): void;
32-
}
15+
};
3316

3417
export function isAbortSignal(value: unknown): value is AbortSignal {
3518
if (typeof value !== 'object' || value === null) {
@@ -47,32 +30,25 @@ export function isAbortSignal(value: unknown): value is AbortSignal {
4730
* A controller object that allows you to abort an `AbortSignal` when desired.
4831
*
4932
* @remarks
50-
* This interface is compatible with the `AbortController` interface defined in TypeScript's DOM types.
51-
* It is redefined here, so it can be polyfilled without a DOM, for example with
52-
* {@link https://www.npmjs.com/package/abortcontroller-polyfill | abortcontroller-polyfill} in a Node environment.
33+
* This is equivalent to the `AbortController` interface defined in TypeScript's DOM types or `@types/node`.
5334
*
5435
* @internal
5536
*/
56-
export interface AbortController {
37+
// Trick with globalThis inspired by @types/node
38+
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0c370ead967cb97b1758d8fa15d09011fb3f58ea/types/node/globals.d.ts#L226
39+
export type AbortController = typeof globalThis extends { AbortController: { prototype: infer T } } ? T : {
5740
readonly signal: AbortSignal;
58-
5941
abort(reason?: any): void;
60-
}
61-
62-
interface AbortControllerConstructor {
63-
new(): AbortController;
64-
}
65-
66-
const supportsAbortController = typeof (AbortController as any) === 'function';
42+
};
6743

6844
/**
6945
* Construct a new AbortController, if supported by the platform.
7046
*
7147
* @internal
7248
*/
7349
export function createAbortController(): AbortController | undefined {
74-
if (supportsAbortController) {
75-
return new (AbortController as AbortControllerConstructor)();
50+
if (typeof AbortController === 'function') {
51+
return new AbortController();
7652
}
7753
return undefined;
7854
}

src/lib/readable-stream/async-iterator.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference lib="es2018.asynciterable" />
2-
31
import { ReadableStream } from '../readable-stream';
42
import {
53
AcquireReadableStreamDefaultReader,

src/stub/dom-exception.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
/// <reference types="node" />
21
import { globals } from '../globals';
32
import { setFunctionName } from '../lib/helpers/miscellaneous';
43

4+
declare global {
5+
interface ErrorConstructor {
6+
// From @types/node
7+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
8+
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
9+
}
10+
}
11+
512
interface DOMException extends Error {
613
name: string;
714
message: string;

src/stub/math-trunc.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference lib="es2015.core" />
2-
31
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill
42
const MathTrunc: typeof Math.trunc = Math.trunc || function (v) {
53
return v < 0 ? Math.ceil(v) : Math.floor(v);

src/stub/number-isfinite.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference lib="es2015.core" />
2-
31
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
42
const NumberIsFinite: typeof Number.isFinite = Number.isFinite || function (x) {
53
return typeof x === 'number' && isFinite(x);

src/stub/number-isinteger.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference lib="es2015.core" />
2-
31
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger#Polyfill
42
const NumberIsInteger: typeof Number.isInteger = Number.isInteger || function (value) {
53
return typeof value === 'number'

src/stub/number-isnan.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/// <reference lib="es2015.core" />
2-
31
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
42
const NumberIsNaN: typeof Number.isNaN = Number.isNaN || function (x) {
53
// eslint-disable-next-line no-self-compare

0 commit comments

Comments
 (0)