Skip to content

Commit de9096b

Browse files
TypeScript Botahejlsberg
TypeScript Bot
andauthored
🤖 Pick PR #57871 (Divide-and-conquer strategy for int...) into release-5.4 (#57893)
Co-authored-by: Anders Hejlsberg <[email protected]>
1 parent 06aae98 commit de9096b

File tree

4 files changed

+706
-0
lines changed

4 files changed

+706
-0
lines changed

‎src/compiler/checker.ts

+8
Original file line numberDiff line numberDiff line change
@@ -17678,6 +17678,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1767817678
removeFromEach(typeSet, TypeFlags.Null);
1767917679
result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
1768017680
}
17681+
else if (typeSet.length >= 4) {
17682+
// When we have four or more constituents, some of which are unions, we employ a "divide and conquer" strategy
17683+
// where A & B & C & D is processed as (A & B) & (C & D). Since intersections of unions often produce far smaller
17684+
// unions of intersections than the full cartesian product (due to some intersections becoming `never`), this can
17685+
// dramatically reduce the overall work.
17686+
const middle = Math.floor(typeSet.length / 2);
17687+
result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle)), getIntersectionType(typeSet.slice(middle))], aliasSymbol, aliasTypeArguments);
17688+
}
1768117689
else {
1768217690
// We are attempting to construct a type of the form X & (A | B) & (C | D). Transform this into a type of
1768317691
// the form X & A & C | X & A & D | X & B & C | X & B & D. If the estimated size of the resulting union type
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
//// [tests/cases/compiler/divideAndConquerIntersections.ts] ////
2+
3+
=== divideAndConquerIntersections.ts ===
4+
type QQ<T extends string[]> =
5+
>QQ : Symbol(QQ, Decl(divideAndConquerIntersections.ts, 0, 0))
6+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
7+
8+
& ("a" | T[0])
9+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
10+
11+
& ("b" | T[1])
12+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
13+
14+
& ("c" | T[2])
15+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
16+
17+
& ("d" | T[3])
18+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
19+
20+
& ("e" | T[4])
21+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
22+
23+
& ("f" | T[5])
24+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
25+
26+
& ("g" | T[6])
27+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
28+
29+
& ("h" | T[7])
30+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
31+
32+
& ("i" | T[8])
33+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
34+
35+
& ("j" | T[9])
36+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
37+
38+
& ("k" | T[10])
39+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
40+
41+
& ("l" | T[11])
42+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
43+
44+
& ("m" | T[12])
45+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
46+
47+
& ("n" | T[13])
48+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
49+
50+
& ("q" | T[14])
51+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
52+
53+
& ("p" | T[15])
54+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
55+
56+
& ("q" | T[16])
57+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
58+
59+
& ("r" | T[17])
60+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
61+
62+
& ("s" | T[18])
63+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
64+
65+
& ("t" | T[19]);
66+
>T : Symbol(T, Decl(divideAndConquerIntersections.ts, 0, 8))
67+
68+
// Repro from #57863
69+
70+
export interface Update {
71+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
72+
73+
update_id: number;
74+
>update_id : Symbol(Update.update_id, Decl(divideAndConquerIntersections.ts, 24, 25))
75+
76+
message?: { message: string };
77+
>message : Symbol(Update.message, Decl(divideAndConquerIntersections.ts, 25, 22))
78+
>message : Symbol(message, Decl(divideAndConquerIntersections.ts, 27, 15))
79+
80+
edited_message?: { edited_message: string };
81+
>edited_message : Symbol(Update.edited_message, Decl(divideAndConquerIntersections.ts, 27, 34))
82+
>edited_message : Symbol(edited_message, Decl(divideAndConquerIntersections.ts, 28, 22))
83+
84+
channel_post?: { channel_post: string };
85+
>channel_post : Symbol(Update.channel_post, Decl(divideAndConquerIntersections.ts, 28, 48))
86+
>channel_post : Symbol(channel_post, Decl(divideAndConquerIntersections.ts, 29, 20))
87+
88+
edited_channel_post?: { edited_channel_post: string };
89+
>edited_channel_post : Symbol(Update.edited_channel_post, Decl(divideAndConquerIntersections.ts, 29, 44))
90+
>edited_channel_post : Symbol(edited_channel_post, Decl(divideAndConquerIntersections.ts, 30, 27))
91+
92+
message_reaction?: { message_reaction: string };
93+
>message_reaction : Symbol(Update.message_reaction, Decl(divideAndConquerIntersections.ts, 30, 58))
94+
>message_reaction : Symbol(message_reaction, Decl(divideAndConquerIntersections.ts, 31, 24))
95+
96+
message_reaction_count?: { message_reaction_count: string };
97+
>message_reaction_count : Symbol(Update.message_reaction_count, Decl(divideAndConquerIntersections.ts, 31, 52))
98+
>message_reaction_count : Symbol(message_reaction_count, Decl(divideAndConquerIntersections.ts, 32, 30))
99+
100+
inline_query?: { inline_query: string };
101+
>inline_query : Symbol(Update.inline_query, Decl(divideAndConquerIntersections.ts, 32, 64))
102+
>inline_query : Symbol(inline_query, Decl(divideAndConquerIntersections.ts, 33, 20))
103+
104+
chosen_inline_result?: { chosen_inline_result: string };
105+
>chosen_inline_result : Symbol(Update.chosen_inline_result, Decl(divideAndConquerIntersections.ts, 33, 44))
106+
>chosen_inline_result : Symbol(chosen_inline_result, Decl(divideAndConquerIntersections.ts, 34, 28))
107+
108+
callback_query?: { callback_query: string };
109+
>callback_query : Symbol(Update.callback_query, Decl(divideAndConquerIntersections.ts, 34, 60))
110+
>callback_query : Symbol(callback_query, Decl(divideAndConquerIntersections.ts, 35, 22))
111+
112+
shipping_query?: { shipping_query: string };
113+
>shipping_query : Symbol(Update.shipping_query, Decl(divideAndConquerIntersections.ts, 35, 48))
114+
>shipping_query : Symbol(shipping_query, Decl(divideAndConquerIntersections.ts, 36, 22))
115+
116+
pre_checkout_query?: { pre_checkout_query: string };
117+
>pre_checkout_query : Symbol(Update.pre_checkout_query, Decl(divideAndConquerIntersections.ts, 36, 48))
118+
>pre_checkout_query : Symbol(pre_checkout_query, Decl(divideAndConquerIntersections.ts, 37, 26))
119+
120+
poll?: { poll: string };
121+
>poll : Symbol(Update.poll, Decl(divideAndConquerIntersections.ts, 37, 56))
122+
>poll : Symbol(poll, Decl(divideAndConquerIntersections.ts, 38, 12))
123+
124+
poll_answer?: { poll_answer: string };
125+
>poll_answer : Symbol(Update.poll_answer, Decl(divideAndConquerIntersections.ts, 38, 28))
126+
>poll_answer : Symbol(poll_answer, Decl(divideAndConquerIntersections.ts, 39, 19))
127+
128+
my_chat_member?: { my_chat_member: string };
129+
>my_chat_member : Symbol(Update.my_chat_member, Decl(divideAndConquerIntersections.ts, 39, 42))
130+
>my_chat_member : Symbol(my_chat_member, Decl(divideAndConquerIntersections.ts, 40, 22))
131+
132+
chat_member?: { chat_member: string };
133+
>chat_member : Symbol(Update.chat_member, Decl(divideAndConquerIntersections.ts, 40, 48))
134+
>chat_member : Symbol(chat_member, Decl(divideAndConquerIntersections.ts, 41, 19))
135+
136+
chat_join_request?: { chat_join_request: string };
137+
>chat_join_request : Symbol(Update.chat_join_request, Decl(divideAndConquerIntersections.ts, 41, 42))
138+
>chat_join_request : Symbol(chat_join_request, Decl(divideAndConquerIntersections.ts, 42, 25))
139+
140+
chat_boost?: { chat_boost: string };
141+
>chat_boost : Symbol(Update.chat_boost, Decl(divideAndConquerIntersections.ts, 42, 54))
142+
>chat_boost : Symbol(chat_boost, Decl(divideAndConquerIntersections.ts, 43, 18))
143+
144+
removed_chat_boost?: { removed_chat_boost: string };
145+
>removed_chat_boost : Symbol(Update.removed_chat_boost, Decl(divideAndConquerIntersections.ts, 43, 40))
146+
>removed_chat_boost : Symbol(removed_chat_boost, Decl(divideAndConquerIntersections.ts, 44, 26))
147+
}
148+
149+
type FilterFunction<U extends Update, V extends U> = (up: U) => up is V;
150+
>FilterFunction : Symbol(FilterFunction, Decl(divideAndConquerIntersections.ts, 45, 1))
151+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 47, 20))
152+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
153+
>V : Symbol(V, Decl(divideAndConquerIntersections.ts, 47, 37))
154+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 47, 20))
155+
>up : Symbol(up, Decl(divideAndConquerIntersections.ts, 47, 54))
156+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 47, 20))
157+
>up : Symbol(up, Decl(divideAndConquerIntersections.ts, 47, 54))
158+
>V : Symbol(V, Decl(divideAndConquerIntersections.ts, 47, 37))
159+
160+
export function matchFilter<U extends Update, Q extends FilterQuery>(
161+
>matchFilter : Symbol(matchFilter, Decl(divideAndConquerIntersections.ts, 47, 72))
162+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 49, 28))
163+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
164+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 49, 45))
165+
>FilterQuery : Symbol(FilterQuery, Decl(divideAndConquerIntersections.ts, 55, 1))
166+
167+
filter: Q | Q[],
168+
>filter : Symbol(filter, Decl(divideAndConquerIntersections.ts, 49, 69))
169+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 49, 45))
170+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 49, 45))
171+
172+
): FilterFunction<U, Filter<U, Q>> {
173+
>FilterFunction : Symbol(FilterFunction, Decl(divideAndConquerIntersections.ts, 45, 1))
174+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 49, 28))
175+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
176+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 49, 28))
177+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 49, 45))
178+
179+
// ^ errors out
180+
console.log("Matching", filter);
181+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
182+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
183+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
184+
>filter : Symbol(filter, Decl(divideAndConquerIntersections.ts, 49, 69))
185+
186+
return (up: U): up is Filter<U, Q> => !!up;
187+
>up : Symbol(up, Decl(divideAndConquerIntersections.ts, 54, 12))
188+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 49, 28))
189+
>up : Symbol(up, Decl(divideAndConquerIntersections.ts, 54, 12))
190+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
191+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 49, 28))
192+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 49, 45))
193+
>up : Symbol(up, Decl(divideAndConquerIntersections.ts, 54, 12))
194+
}
195+
196+
/** All valid filter queries (every update key except update_id) */
197+
export type FilterQuery = keyof Omit<Update, "update_id">;
198+
>FilterQuery : Symbol(FilterQuery, Decl(divideAndConquerIntersections.ts, 55, 1))
199+
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
200+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
201+
202+
/** Narrow down an update object based on a filter query */
203+
export type Filter<U extends Update, Q extends FilterQuery> = PerformQuery<
204+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
205+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 61, 19))
206+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
207+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 61, 36))
208+
>FilterQuery : Symbol(FilterQuery, Decl(divideAndConquerIntersections.ts, 55, 1))
209+
>PerformQuery : Symbol(PerformQuery, Decl(divideAndConquerIntersections.ts, 75, 12))
210+
211+
U,
212+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 61, 19))
213+
214+
RunQuery<Q>
215+
>RunQuery : Symbol(RunQuery, Decl(divideAndConquerIntersections.ts, 64, 2))
216+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 61, 36))
217+
218+
>;
219+
220+
// generate an object structure that can be intersected with updates to narrow them down
221+
type RunQuery<Q extends string> = Combine<L1Fragment<Q>, Q>;
222+
>RunQuery : Symbol(RunQuery, Decl(divideAndConquerIntersections.ts, 64, 2))
223+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 67, 14))
224+
>Combine : Symbol(Combine, Decl(divideAndConquerIntersections.ts, 71, 12))
225+
>L1Fragment : Symbol(L1Fragment, Decl(divideAndConquerIntersections.ts, 67, 60))
226+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 67, 14))
227+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 67, 14))
228+
229+
// maps each part of the filter query to Record<"key", object>
230+
type L1Fragment<Q extends string> = Q extends unknown ? Record<Q, object>
231+
>L1Fragment : Symbol(L1Fragment, Decl(divideAndConquerIntersections.ts, 67, 60))
232+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 70, 16))
233+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 70, 16))
234+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
235+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 70, 16))
236+
237+
: never;
238+
// define all other fields from query as keys with value `undefined`
239+
type Combine<U, K extends string> = U extends unknown
240+
>Combine : Symbol(Combine, Decl(divideAndConquerIntersections.ts, 71, 12))
241+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 73, 13))
242+
>K : Symbol(K, Decl(divideAndConquerIntersections.ts, 73, 15))
243+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 73, 13))
244+
245+
? U & Partial<Record<Exclude<K, keyof U>, undefined>>
246+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 73, 13))
247+
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
248+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
249+
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
250+
>K : Symbol(K, Decl(divideAndConquerIntersections.ts, 73, 15))
251+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 73, 13))
252+
253+
: never;
254+
255+
// apply a query result by intersecting it with update,
256+
// and then using these values to override the actual update
257+
type PerformQuery<U extends Update, R extends object> = R extends unknown
258+
>PerformQuery : Symbol(PerformQuery, Decl(divideAndConquerIntersections.ts, 75, 12))
259+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 79, 18))
260+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
261+
>R : Symbol(R, Decl(divideAndConquerIntersections.ts, 79, 35))
262+
>R : Symbol(R, Decl(divideAndConquerIntersections.ts, 79, 35))
263+
264+
? FilteredEvent<U, Update & R>
265+
>FilteredEvent : Symbol(FilteredEvent, Decl(divideAndConquerIntersections.ts, 81, 12))
266+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 79, 18))
267+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
268+
>R : Symbol(R, Decl(divideAndConquerIntersections.ts, 79, 35))
269+
270+
: never;
271+
272+
// narrow down an update by intersecting it with a different update
273+
type FilteredEvent<E extends Update, U extends Update> =
274+
>FilteredEvent : Symbol(FilteredEvent, Decl(divideAndConquerIntersections.ts, 81, 12))
275+
>E : Symbol(E, Decl(divideAndConquerIntersections.ts, 84, 19))
276+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
277+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 84, 36))
278+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
279+
280+
& E
281+
>E : Symbol(E, Decl(divideAndConquerIntersections.ts, 84, 19))
282+
283+
& Omit<U, "update_id">;
284+
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
285+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 84, 36))
286+
287+
type Middleware<U extends Update> = (ctx: U) => unknown | Promise<unknown>;
288+
>Middleware : Symbol(Middleware, Decl(divideAndConquerIntersections.ts, 86, 27))
289+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 88, 16))
290+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
291+
>ctx : Symbol(ctx, Decl(divideAndConquerIntersections.ts, 88, 37))
292+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 88, 16))
293+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
294+
295+
class EventHub<U extends Update> {
296+
>EventHub : Symbol(EventHub, Decl(divideAndConquerIntersections.ts, 88, 75))
297+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
298+
>Update : Symbol(Update, Decl(divideAndConquerIntersections.ts, 20, 20))
299+
300+
use(...middleware: Array<Middleware<U>>): EventHub<U> {
301+
>use : Symbol(EventHub.use, Decl(divideAndConquerIntersections.ts, 89, 34))
302+
>middleware : Symbol(middleware, Decl(divideAndConquerIntersections.ts, 90, 8))
303+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
304+
>Middleware : Symbol(Middleware, Decl(divideAndConquerIntersections.ts, 86, 27))
305+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
306+
>EventHub : Symbol(EventHub, Decl(divideAndConquerIntersections.ts, 88, 75))
307+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
308+
309+
console.log("Adding", middleware.length, "generic handlers");
310+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
311+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
312+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
313+
>middleware.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
314+
>middleware : Symbol(middleware, Decl(divideAndConquerIntersections.ts, 90, 8))
315+
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
316+
317+
return this;
318+
>this : Symbol(EventHub, Decl(divideAndConquerIntersections.ts, 88, 75))
319+
}
320+
on<Q extends FilterQuery>(
321+
>on : Symbol(EventHub.on, Decl(divideAndConquerIntersections.ts, 93, 5))
322+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
323+
>FilterQuery : Symbol(FilterQuery, Decl(divideAndConquerIntersections.ts, 55, 1))
324+
325+
filter: Q | Q[],
326+
>filter : Symbol(filter, Decl(divideAndConquerIntersections.ts, 94, 30))
327+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
328+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
329+
330+
...middleware: Array<Middleware<Filter<U, Q>>>
331+
>middleware : Symbol(middleware, Decl(divideAndConquerIntersections.ts, 95, 24))
332+
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
333+
>Middleware : Symbol(Middleware, Decl(divideAndConquerIntersections.ts, 86, 27))
334+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
335+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
336+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
337+
338+
// ^ errors out
339+
): EventHub<Filter<U, Q>> {
340+
>EventHub : Symbol(EventHub, Decl(divideAndConquerIntersections.ts, 88, 75))
341+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
342+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
343+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
344+
345+
console.log("Adding", middleware.length, "handlers for", filter);
346+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
347+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
348+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
349+
>middleware.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
350+
>middleware : Symbol(middleware, Decl(divideAndConquerIntersections.ts, 95, 24))
351+
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
352+
>filter : Symbol(filter, Decl(divideAndConquerIntersections.ts, 94, 30))
353+
354+
return new EventHub<Filter<U, Q>>();
355+
>EventHub : Symbol(EventHub, Decl(divideAndConquerIntersections.ts, 88, 75))
356+
>Filter : Symbol(Filter, Decl(divideAndConquerIntersections.ts, 58, 58))
357+
>U : Symbol(U, Decl(divideAndConquerIntersections.ts, 89, 15))
358+
>Q : Symbol(Q, Decl(divideAndConquerIntersections.ts, 94, 7))
359+
}
360+
}
361+

0 commit comments

Comments
 (0)