Skip to content

Commit f41145b

Browse files
committed
TS: Fix strict issues in src/subscription
1 parent 6858154 commit f41145b

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

src/subscription/__tests__/mapAsyncIterator-test.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ describe('mapAsyncIterator', () => {
3333

3434
next(): Promise<IteratorResult<number, void>> {
3535
if (items.length > 0) {
36-
return Promise.resolve({ done: false, value: items.shift() });
36+
const value = items[0];
37+
items.shift();
38+
return Promise.resolve({ done: false, value });
3739
}
3840

3941
return Promise.resolve({ done: true, value: undefined });
@@ -105,8 +107,7 @@ describe('mapAsyncIterator', () => {
105107
expect(await doubles.next()).to.deep.equal({ value: 4, done: false });
106108

107109
// Early return
108-
// @ts-expect-error FIXME: TS Conversion
109-
expect(await doubles.return()).to.deep.equal({
110+
expect(await doubles.return('')).to.deep.equal({
110111
value: 'The End',
111112
done: true,
112113
});
@@ -130,9 +131,11 @@ describe('mapAsyncIterator', () => {
130131
return this;
131132
},
132133
next() {
134+
const value = items[0];
135+
items.shift();
133136
return Promise.resolve({
134137
done: items.length === 0,
135-
value: items.shift(),
138+
value,
136139
});
137140
},
138141
};
@@ -143,8 +146,7 @@ describe('mapAsyncIterator', () => {
143146
expect(await doubles.next()).to.deep.equal({ value: 4, done: false });
144147

145148
// Early return
146-
// @ts-expect-error FIXME: TS Conversion
147-
expect(await doubles.return()).to.deep.equal({
149+
expect(await doubles.return(0)).to.deep.equal({
148150
value: undefined,
149151
done: true,
150152
});
@@ -194,9 +196,11 @@ describe('mapAsyncIterator', () => {
194196
return this;
195197
},
196198
next() {
199+
const value = items[0];
200+
items.shift();
197201
return Promise.resolve({
198202
done: items.length === 0,
199-
value: items.shift(),
203+
value,
200204
});
201205
},
202206
};

src/subscription/__tests__/simplePubSub.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { invariant } from '../../jsutils/invariant';
2+
13
/**
24
* Create an AsyncIterator from an EventEmitter. Useful for mocking a
35
* PubSub system for tests.
@@ -18,7 +20,7 @@ export class SimplePubSub<T> {
1820

1921
getSubscriber<R>(transform: (value: T) => R): AsyncGenerator<R, void, void> {
2022
const pullQueue: Array<(result: IteratorResult<R, void>) => void> = [];
21-
const pushQueue = [];
23+
const pushQueue: Array<R> = [];
2224
let listening = true;
2325
this._subscribers.add(pushValue);
2426

@@ -33,13 +35,15 @@ export class SimplePubSub<T> {
3335
};
3436

3537
return {
36-
next() {
38+
next(): Promise<IteratorResult<R, void>> {
3739
if (!listening) {
3840
return Promise.resolve({ value: undefined, done: true });
3941
}
4042

4143
if (pushQueue.length > 0) {
42-
return Promise.resolve({ value: pushQueue.shift(), done: false });
44+
const value = pushQueue[0];
45+
pushQueue.shift();
46+
return Promise.resolve({ value, done: false });
4347
}
4448
return new Promise((resolve) => pullQueue.push(resolve));
4549
},
@@ -59,7 +63,9 @@ export class SimplePubSub<T> {
5963
function pushValue(event: T): void {
6064
const value: R = transform(event);
6165
if (pullQueue.length > 0) {
62-
pullQueue.shift()({ value, done: false });
66+
const receiver = pullQueue.shift();
67+
invariant(receiver);
68+
receiver({ value, done: false });
6369
} else {
6470
pushQueue.push(value);
6571
}

src/subscription/__tests__/subscribe-test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ const InboxType = new GraphQLObjectType({
4242
},
4343
unread: {
4444
type: GraphQLInt,
45-
resolve: (inbox) => inbox.emails.filter((email) => email.unread).length,
45+
resolve: (inbox) =>
46+
inbox.emails.filter((email: any) => email.unread).length,
4647
},
4748
emails: { type: new GraphQLList(EmailType) },
4849
},
@@ -103,7 +104,7 @@ function createSubscription(pubsub: SimplePubSub<Email>) {
103104
},
104105
];
105106

106-
const data = {
107+
const data: any = {
107108
inbox: { emails },
108109
// FIXME: we shouldn't use mapAsyncIterator here since it makes tests way more complex
109110
importantEmail: pubsub.getSubscriber((newEmail) => {
@@ -122,7 +123,7 @@ function createSubscription(pubsub: SimplePubSub<Email>) {
122123
}
123124

124125
async function expectPromise(promise: Promise<unknown>) {
125-
let caughtError;
126+
let caughtError: Error;
126127

127128
try {
128129
await promise;
@@ -136,7 +137,7 @@ async function expectPromise(promise: Promise<unknown>) {
136137
toReject() {
137138
expect(caughtError).to.be.an.instanceOf(Error);
138139
},
139-
toRejectWith(message) {
140+
toRejectWith(message: string) {
140141
expect(caughtError).to.be.an.instanceOf(Error);
141142
expect(caughtError).to.have.property('message', message);
142143
},
@@ -312,6 +313,7 @@ describe('Subscription Initialization Phase', () => {
312313
}),
313314
});
314315

316+
// TODO ts-expect-error (schema must not be null)
315317
(await expectPromise(subscribe({ schema: null, document }))).toRejectWith(
316318
'Expected null to be a GraphQL schema.',
317319
);
@@ -321,6 +323,7 @@ describe('Subscription Initialization Phase', () => {
321323
'Expected undefined to be a GraphQL schema.',
322324
);
323325

326+
// TODO ts-expect-error (document must not be null)
324327
(await expectPromise(subscribe({ schema, document: null }))).toRejectWith(
325328
'Must provide document.',
326329
);

src/subscription/mapAsyncIterator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export function mapAsyncIterator<T, U, R = undefined>(
88
iterable: AsyncGenerator<T, R, void> | AsyncIterable<T>,
99
callback: (value: T) => PromiseOrValue<U>,
1010
): AsyncGenerator<U, R, void> {
11-
// $FlowIssue[incompatible-use]
1211
const iterator = iterable[Symbol.asyncIterator]();
1312

1413
async function mapResult(
@@ -39,9 +38,10 @@ export function mapAsyncIterator<T, U, R = undefined>(
3938
return mapResult(await iterator.next());
4039
},
4140
async return(): Promise<IteratorResult<U, R>> {
41+
// If iterator.return() does not exist, then type R must be undefined.
4242
return typeof iterator.return === 'function'
4343
? mapResult(await iterator.return())
44-
: { value: undefined, done: true };
44+
: { value: undefined as any, done: true };
4545
},
4646
async throw(error?: unknown) {
4747
return typeof iterator.throw === 'function'

src/subscription/subscribe.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export async function subscribe(
9292
// the GraphQL specification. The `execute` function provides the
9393
// "ExecuteSubscriptionEvent" algorithm, as it is nearly identical to the
9494
// "ExecuteQuery" algorithm, for which `execute` is also used.
95-
const mapSourceToResponse = (payload) =>
95+
const mapSourceToResponse = (payload: unknown) =>
9696
execute({
9797
schema,
9898
document,
@@ -161,11 +161,10 @@ export async function createSourceEventStream(
161161
);
162162

163163
// Return early errors if execution context failed.
164-
if (Array.isArray(exeContext)) {
164+
if (!('schema' in exeContext)) {
165165
return { errors: exeContext };
166166
}
167167

168-
// @ts-expect-error FIXME: TS Conversion
169168
const eventStream = await executeSubscription(exeContext);
170169

171170
// Assert field returned an event stream, otherwise yield an error.

0 commit comments

Comments
 (0)