ripple 0.3.67 → 0.3.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -2
- package/src/runtime/element.js +1 -1
- package/src/runtime/index-client.js +11 -11
- package/src/runtime/index-server.js +7 -4
- package/src/runtime/internal/client/bindings.js +1 -1
- package/src/runtime/internal/client/blocks.js +13 -4
- package/src/runtime/internal/client/component.js +55 -0
- package/src/runtime/internal/client/composite.js +4 -2
- package/src/runtime/internal/client/expression.js +65 -7
- package/src/runtime/internal/client/hmr.js +54 -43
- package/src/runtime/internal/client/index.js +5 -1
- package/src/runtime/internal/client/portal.js +70 -69
- package/src/runtime/internal/client/render.js +3 -0
- package/src/runtime/internal/server/index.js +92 -8
- package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
- package/tests/client/array/array.copy-within.test.tsrx +33 -31
- package/tests/client/array/array.derived.test.tsrx +186 -169
- package/tests/client/array/array.iteration.test.tsrx +40 -37
- package/tests/client/array/array.mutations.test.tsrx +113 -101
- package/tests/client/array/array.static.test.tsrx +119 -101
- package/tests/client/array/array.to-methods.test.tsrx +24 -21
- package/tests/client/async-suspend.test.tsrx +247 -246
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
- package/tests/client/basic/basic.attributes.test.tsrx +428 -423
- package/tests/client/basic/basic.collections.test.tsrx +109 -102
- package/tests/client/basic/basic.components.test.tsrx +323 -205
- package/tests/client/basic/basic.errors.test.tsrx +91 -91
- package/tests/client/basic/basic.events.test.tsrx +114 -115
- package/tests/client/basic/basic.get-set.test.tsrx +97 -87
- package/tests/client/basic/basic.hmr.test.tsrx +19 -16
- package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
- package/tests/client/basic/basic.rendering.test.tsrx +272 -182
- package/tests/client/basic/basic.styling.test.tsrx +23 -22
- package/tests/client/basic/basic.utilities.test.tsrx +10 -8
- package/tests/client/boundaries.test.tsrx +26 -26
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
- package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
- package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
- package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
- package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
- package/tests/client/composite/composite.generics.test.tsrx +168 -192
- package/tests/client/composite/composite.props.test.tsrx +97 -81
- package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
- package/tests/client/composite/composite.render.test.tsrx +122 -105
- package/tests/client/computed-properties.test.tsrx +28 -28
- package/tests/client/context.test.tsrx +21 -21
- package/tests/client/css/global-additional-cases.test.tsrx +58 -58
- package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
- package/tests/client/css/global-at-rules.test.tsrx +10 -10
- package/tests/client/css/global-basic.test.tsrx +14 -14
- package/tests/client/css/global-classes-ids.test.tsrx +14 -14
- package/tests/client/css/global-combinators.test.tsrx +10 -10
- package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
- package/tests/client/css/global-edge-cases.test.tsrx +18 -18
- package/tests/client/css/global-keyframes.test.tsrx +12 -12
- package/tests/client/css/global-nested.test.tsrx +10 -10
- package/tests/client/css/global-pseudo.test.tsrx +12 -12
- package/tests/client/css/global-scoping.test.tsrx +20 -20
- package/tests/client/css/style-identifier.test.tsrx +143 -291
- package/tests/client/date.test.tsrx +146 -133
- package/tests/client/dynamic-elements.test.tsrx +398 -365
- package/tests/client/events.test.tsrx +292 -290
- package/tests/client/for.test.tsrx +156 -153
- package/tests/client/head.test.tsrx +105 -96
- package/tests/client/html.test.tsrx +122 -26
- package/tests/client/input-value.test.tsrx +1361 -1314
- package/tests/client/lazy-array.test.tsrx +16 -13
- package/tests/client/lazy-destructuring.test.tsrx +257 -213
- package/tests/client/map.test.tsrx +65 -60
- package/tests/client/media-query.test.tsrx +22 -20
- package/tests/client/object.test.tsrx +87 -81
- package/tests/client/portal.test.tsrx +57 -51
- package/tests/client/ref.test.tsrx +233 -202
- package/tests/client/return.test.tsrx +71 -2560
- package/tests/client/set.test.tsrx +54 -45
- package/tests/client/svg.test.tsrx +216 -186
- package/tests/client/switch.test.tsrx +194 -193
- package/tests/client/track-async-hydration.test.tsrx +18 -14
- package/tests/client/tracked-index-access.test.tsrx +28 -18
- package/tests/client/try.test.tsrx +675 -548
- package/tests/client/tsx.test.tsrx +373 -311
- package/tests/client/typescript-generics.test.tsrx +145 -145
- package/tests/client/url/url.derived.test.tsrx +33 -28
- package/tests/client/url/url.parsing.test.tsrx +61 -51
- package/tests/client/url/url.partial-removal.test.tsrx +56 -48
- package/tests/client/url/url.reactivity.test.tsrx +142 -125
- package/tests/client/url/url.serialization.test.tsrx +13 -11
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
- package/tests/hydration/basic.test.js +3 -3
- package/tests/hydration/compiled/client/basic.js +586 -651
- package/tests/hydration/compiled/client/composite.js +79 -104
- package/tests/hydration/compiled/client/events.js +140 -148
- package/tests/hydration/compiled/client/for.js +1005 -1018
- package/tests/hydration/compiled/client/head.js +124 -134
- package/tests/hydration/compiled/client/hmr.js +41 -48
- package/tests/hydration/compiled/client/html-in-template.js +38 -41
- package/tests/hydration/compiled/client/html.js +970 -1314
- package/tests/hydration/compiled/client/if-children.js +234 -249
- package/tests/hydration/compiled/client/if.js +182 -189
- package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
- package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
- package/tests/hydration/compiled/client/portal.js +65 -85
- package/tests/hydration/compiled/client/reactivity.js +84 -90
- package/tests/hydration/compiled/client/return.js +38 -1939
- package/tests/hydration/compiled/client/switch.js +218 -224
- package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
- package/tests/hydration/compiled/client/try.js +123 -132
- package/tests/hydration/compiled/server/basic.js +773 -831
- package/tests/hydration/compiled/server/composite.js +166 -191
- package/tests/hydration/compiled/server/events.js +170 -184
- package/tests/hydration/compiled/server/for.js +851 -909
- package/tests/hydration/compiled/server/head.js +206 -216
- package/tests/hydration/compiled/server/hmr.js +64 -72
- package/tests/hydration/compiled/server/html-in-template.js +42 -76
- package/tests/hydration/compiled/server/html.js +1362 -1667
- package/tests/hydration/compiled/server/if-children.js +419 -445
- package/tests/hydration/compiled/server/if.js +194 -208
- package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
- package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
- package/tests/hydration/compiled/server/portal.js +152 -160
- package/tests/hydration/compiled/server/reactivity.js +94 -106
- package/tests/hydration/compiled/server/return.js +28 -2172
- package/tests/hydration/compiled/server/switch.js +274 -286
- package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
- package/tests/hydration/compiled/server/try.js +167 -185
- package/tests/hydration/components/basic.tsrx +320 -272
- package/tests/hydration/components/composite.tsrx +44 -32
- package/tests/hydration/components/events.tsrx +101 -91
- package/tests/hydration/components/for.tsrx +510 -452
- package/tests/hydration/components/head.tsrx +87 -80
- package/tests/hydration/components/hmr.tsrx +22 -17
- package/tests/hydration/components/html-in-template.tsrx +22 -17
- package/tests/hydration/components/html.tsrx +525 -443
- package/tests/hydration/components/if-children.tsrx +158 -148
- package/tests/hydration/components/if.tsrx +109 -95
- package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
- package/tests/hydration/components/nested-control-flow.tsrx +215 -203
- package/tests/hydration/components/portal.tsrx +41 -34
- package/tests/hydration/components/reactivity.tsrx +37 -27
- package/tests/hydration/components/return.tsrx +12 -556
- package/tests/hydration/components/switch.tsrx +120 -114
- package/tests/hydration/components/track-async-serialization.tsrx +107 -91
- package/tests/hydration/components/try.tsrx +55 -40
- package/tests/hydration/html.test.js +4 -4
- package/tests/hydration/return.test.js +13 -532
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +264 -195
- package/tests/server/basic.components.test.tsrx +296 -169
- package/tests/server/basic.test.tsrx +300 -198
- package/tests/server/compiler.test.tsrx +62 -60
- package/tests/server/composite.props.test.tsrx +77 -63
- package/tests/server/composite.test.tsrx +168 -192
- package/tests/server/context.test.tsrx +18 -12
- package/tests/server/dynamic-elements.test.tsrx +197 -180
- package/tests/server/for.test.tsrx +85 -78
- package/tests/server/head.test.tsrx +50 -43
- package/tests/server/html-nesting-validation.test.tsrx +8 -8
- package/tests/server/if.test.tsrx +57 -51
- package/tests/server/lazy-destructuring.test.tsrx +366 -294
- package/tests/server/return.test.tsrx +76 -1355
- package/tests/server/streaming-ssr.test.tsrx +4 -75
- package/tests/server/style-identifier.test.tsrx +169 -148
- package/tests/server/switch.test.tsrx +91 -85
- package/tests/server/track-async-serialization.test.tsrx +105 -85
- package/tests/server/try.test.tsrx +374 -280
- package/tests/utils/compiler-compat-config.test.js +2 -2
- package/tests/utils/runtime-imports.test.js +10 -0
- package/types/index.d.ts +8 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
|
@@ -2,213 +2,189 @@ import { RippleArray, RippleMap } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
describe('generics', () => {
|
|
4
4
|
it('handles advanced generic ambiguity and edge cases', () => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
function App() {
|
|
6
|
+
return <>
|
|
7
|
+
const maybe = {
|
|
8
|
+
factory: function <T>() {
|
|
9
|
+
return {
|
|
10
|
+
make: function <U>() {
|
|
11
|
+
return 1;
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
const g = maybe?.factory<number>()?.make<boolean>();
|
|
17
|
+
// 8. Comparison operator (ensure '<' here NOT misparsed as generics)
|
|
18
|
+
let x = 10, y = 20;
|
|
19
|
+
const h =
|
|
20
|
+
x < y ? 'lt' : 'ge';
|
|
21
|
+
// 9. Chained comparisons with intervening generics
|
|
22
|
+
class Box<T> {
|
|
23
|
+
value: T;
|
|
24
|
+
|
|
25
|
+
constructor(value: T) {
|
|
26
|
+
this.value = value;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
open<U>() {
|
|
30
|
+
return new Box<number>(1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const limit = 100;
|
|
34
|
+
const i =
|
|
35
|
+
new Box<number>(2).value < limit ? 'ok' : 'no';
|
|
36
|
+
// 10. JSX / Element should still work
|
|
37
|
+
<div class="still-works">
|
|
38
|
+
<span>{'Test'}</span>
|
|
39
|
+
</div>
|
|
40
|
+
// 11. Generic function call vs Element: Identifier followed by generic args
|
|
41
|
+
function identity<T>(value: T): T {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
const j = identity<number>(42);
|
|
45
|
+
// 12. Member + generic call immediately followed by another call
|
|
46
|
+
class Factory {
|
|
47
|
+
create<T>() {
|
|
48
|
+
return (value: T) => value;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const factory = new Factory();
|
|
52
|
+
const k = factory.create<number>()(123);
|
|
53
|
+
// 13. Multiple generic segments in chain
|
|
54
|
+
function foo<T>() {
|
|
55
|
+
return {
|
|
56
|
+
bar: function <U>() {
|
|
57
|
+
return {
|
|
58
|
+
baz: function <V>() {
|
|
59
|
+
return true;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const l = foo<number>().bar<string>().baz<boolean>();
|
|
66
|
+
// 14. Generic with constraint + default
|
|
67
|
+
type Extractor<T extends { id: number } = { id: number }> = (v: T) => number;
|
|
68
|
+
const m: Extractor<{ id: number }> = (v) => v.id;
|
|
69
|
+
// 15. Generic in angle after "new" + trailing call
|
|
70
|
+
class Wrapper<T> {
|
|
71
|
+
value: T;
|
|
72
|
+
|
|
73
|
+
constructor() {
|
|
74
|
+
this.value = null as unknown as T;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
unwrap<U>() {
|
|
78
|
+
return null as unknown as U;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const n = new Wrapper<number>().unwrap<string>();
|
|
82
|
+
// 16. Angle brackets inside type assertion vs generic call
|
|
83
|
+
function getUnknown(): unknown {
|
|
84
|
+
return new Map<string, number>([['a', 1]]);
|
|
85
|
+
}
|
|
86
|
+
getUnknown.factory = function <T>() {
|
|
11
87
|
return {
|
|
12
88
|
make: function <U>() {
|
|
13
|
-
return
|
|
89
|
+
return 2;
|
|
14
90
|
},
|
|
15
91
|
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
constructor(value: T) {
|
|
30
|
-
this.value = value;
|
|
92
|
+
};
|
|
93
|
+
const raw = getUnknown();
|
|
94
|
+
const o = (raw as Map<string, number>).get('a');
|
|
95
|
+
// 17. Generic with comma + trailing less-than comparison on next token
|
|
96
|
+
class Pair<T1, T2> {
|
|
97
|
+
first: T1;
|
|
98
|
+
|
|
99
|
+
second: T2;
|
|
100
|
+
|
|
101
|
+
constructor() {
|
|
102
|
+
this.first = null as unknown as T1;
|
|
103
|
+
this.second = null as unknown as T2;
|
|
104
|
+
}
|
|
31
105
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
106
|
+
const p = new Pair<number, string>();
|
|
107
|
+
const q =
|
|
108
|
+
1 < 2 ? p : null;
|
|
109
|
+
// 18. Nested generics with line breaks resembling JSX indentation
|
|
110
|
+
interface Node<T> {
|
|
111
|
+
value: T;
|
|
35
112
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// 10. JSX / Element should still work
|
|
42
|
-
<div class="still-works">
|
|
43
|
-
<span>{'Test'}</span>
|
|
44
|
-
</div>
|
|
113
|
+
interface Edge<W> {
|
|
114
|
+
weight: W;
|
|
115
|
+
}
|
|
116
|
+
class Graph<N, E> {
|
|
117
|
+
nodes: N[];
|
|
45
118
|
|
|
46
|
-
|
|
47
|
-
function identity<T>(value: T): T {
|
|
48
|
-
return value;
|
|
49
|
-
}
|
|
50
|
-
const j = identity<number>(42);
|
|
119
|
+
edges: E[];
|
|
51
120
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
121
|
+
constructor() {
|
|
122
|
+
this.nodes = [];
|
|
123
|
+
this.edges = [];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const r = new Graph<Node<string>, Edge<number>>();
|
|
127
|
+
// 19. Ternary containing generics in both branches
|
|
128
|
+
let flag = true;
|
|
129
|
+
const s = flag ? new Box<number>(1) : new Box<string>('string');
|
|
130
|
+
// 20. Generic inside template expression
|
|
131
|
+
const t = `length=${new RippleArray<number>().length}`;
|
|
132
|
+
// 21. Optional chaining + generic + property access
|
|
133
|
+
const registry = new RippleMap<string, number>();
|
|
134
|
+
const u = registry.get('id')?.toString();
|
|
135
|
+
// 22. Generic call used as callee for another call
|
|
136
|
+
function make<T>() {
|
|
55
137
|
return (value: T) => value;
|
|
56
138
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
139
|
+
const v = make<number>()(10);
|
|
140
|
+
// 23. Generic followed by tagged template (ensure not confused with JSX)
|
|
141
|
+
function tagFn<T>(strings: TemplateStringsArray, ...values) {
|
|
142
|
+
return values[0];
|
|
143
|
+
}
|
|
144
|
+
const tagResult = tagFn`value`;
|
|
145
|
+
// 24. Sequence mixing: (a < b) + generic call in same statement
|
|
146
|
+
function compute<T>(x: T, y: T): T {
|
|
147
|
+
return y;
|
|
148
|
+
}
|
|
149
|
+
const w = x < y && compute<number>(x, y);
|
|
150
|
+
// Additional component focusing on edge crankers
|
|
151
|
+
|
|
152
|
+
// 28. Generic after parenthesized new expression
|
|
153
|
+
const aa = (new Box<number>(1)).open<string>();
|
|
154
|
+
// 29. Generic chain right after closing paren of IIFE
|
|
155
|
+
class Builder<Kind> {
|
|
156
|
+
finalize<Result>() {
|
|
65
157
|
return {
|
|
66
|
-
|
|
67
|
-
return true;
|
|
68
|
-
},
|
|
158
|
+
result: null as unknown as Result,
|
|
69
159
|
};
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
const l = foo<number>().bar<string>().baz<boolean>();
|
|
74
|
-
|
|
75
|
-
// 14. Generic with constraint + default
|
|
76
|
-
type Extractor<T extends { id: number } = { id: number }> = (v: T) => number;
|
|
77
|
-
const m: Extractor<{ id: number }> = (v) => v.id;
|
|
78
|
-
|
|
79
|
-
// 15. Generic in angle after "new" + trailing call
|
|
80
|
-
class Wrapper<T> {
|
|
81
|
-
value: T;
|
|
82
|
-
|
|
83
|
-
constructor() {
|
|
84
|
-
this.value = null as unknown as T;
|
|
160
|
+
}
|
|
85
161
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return
|
|
162
|
+
const builder = new Builder<Number>();
|
|
163
|
+
const result = (function () {
|
|
164
|
+
return builder;
|
|
165
|
+
}() as Builder<Number>).finalize<boolean>();
|
|
166
|
+
// 30. Angle bracket start of conditional expression line
|
|
167
|
+
function adjust<T>(value: T): T {
|
|
168
|
+
return value;
|
|
89
169
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
make: function <U>() {
|
|
100
|
-
return 2;
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
};
|
|
104
|
-
const raw = getUnknown();
|
|
105
|
-
const o = (raw as Map<string, number>).get('a');
|
|
106
|
-
|
|
107
|
-
// 17. Generic with comma + trailing less-than comparison on next token
|
|
108
|
-
class Pair<T1, T2> {
|
|
109
|
-
first: T1;
|
|
110
|
-
|
|
111
|
-
second: T2;
|
|
112
|
-
|
|
113
|
-
constructor() {
|
|
114
|
-
this.first = null as unknown as T1;
|
|
115
|
-
this.second = null as unknown as T2;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
const p = new Pair<number, string>();
|
|
119
|
-
const q =
|
|
120
|
-
1 < 2 ? p : null;
|
|
121
|
-
|
|
122
|
-
// 18. Nested generics with line breaks resembling JSX indentation
|
|
123
|
-
interface Node<T> {
|
|
124
|
-
value: T;
|
|
125
|
-
}
|
|
126
|
-
interface Edge<W> {
|
|
127
|
-
weight: W;
|
|
128
|
-
}
|
|
129
|
-
class Graph<N, E> {
|
|
130
|
-
nodes: N[];
|
|
131
|
-
|
|
132
|
-
edges: E[];
|
|
133
|
-
|
|
134
|
-
constructor() {
|
|
135
|
-
this.nodes = [];
|
|
136
|
-
this.edges = [];
|
|
170
|
+
const val =
|
|
171
|
+
new Wrapper<number>().value < 100 ? adjust<number>(10) : adjust<number>(20);
|
|
172
|
+
// 32. Generic with comments inside angle list
|
|
173
|
+
class Mapper<Key, Value> {
|
|
174
|
+
map: Map<Key, Value>;
|
|
175
|
+
|
|
176
|
+
constructor() {
|
|
177
|
+
this.map = new Map<Key, Value>();
|
|
178
|
+
}
|
|
137
179
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const t = `length=${new RippleArray<number>().length}`;
|
|
147
|
-
|
|
148
|
-
// 21. Optional chaining + generic + property access
|
|
149
|
-
const registry = new RippleMap<string, number>();
|
|
150
|
-
const u = registry.get('id')?.toString();
|
|
151
|
-
|
|
152
|
-
// 22. Generic call used as callee for another call
|
|
153
|
-
function make<T>() {
|
|
154
|
-
return (value: T) => value;
|
|
155
|
-
}
|
|
156
|
-
const v = make<number>()(10);
|
|
157
|
-
|
|
158
|
-
// 23. Generic followed by tagged template (ensure not confused with JSX)
|
|
159
|
-
function tagFn<T>(strings: TemplateStringsArray, ...values) {
|
|
160
|
-
return values[0];
|
|
161
|
-
}
|
|
162
|
-
const tagResult = tagFn`value`;
|
|
163
|
-
|
|
164
|
-
// 24. Sequence mixing: (a < b) + generic call in same statement
|
|
165
|
-
function compute<T>(x: T, y: T): T {
|
|
166
|
-
return y;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const w = x < y && compute<number>(x, y);
|
|
170
|
-
|
|
171
|
-
// Additional component focusing on edge crankers
|
|
172
|
-
|
|
173
|
-
// 28. Generic after parenthesized new expression
|
|
174
|
-
const aa = (new Box<number>(1)).open<string>();
|
|
175
|
-
|
|
176
|
-
// 29. Generic chain right after closing paren of IIFE
|
|
177
|
-
class Builder<Kind> {
|
|
178
|
-
finalize<Result>() {
|
|
179
|
-
return {
|
|
180
|
-
result: null as unknown as Result,
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
const builder = new Builder<Number>();
|
|
185
|
-
const result = (function () {
|
|
186
|
-
return builder;
|
|
187
|
-
}() as Builder<Number>).finalize<boolean>();
|
|
188
|
-
|
|
189
|
-
// 30. Angle bracket start of conditional expression line
|
|
190
|
-
function adjust<T>(value: T): T {
|
|
191
|
-
return value;
|
|
192
|
-
}
|
|
193
|
-
const val =
|
|
194
|
-
new Wrapper<number>().value < 100 ? adjust<number>(10) : adjust<number>(20);
|
|
195
|
-
|
|
196
|
-
// 32. Generic with comments inside angle list
|
|
197
|
-
class Mapper<Key, Value> {
|
|
198
|
-
map: Map<Key, Value>;
|
|
199
|
-
|
|
200
|
-
constructor() {
|
|
201
|
-
this.map = new Map<Key, Value>();
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
const gg = new Mapper<
|
|
205
|
-
// key type
|
|
206
|
-
string /* value type */,
|
|
207
|
-
number
|
|
208
|
-
>();
|
|
209
|
-
|
|
210
|
-
// 33. Map of generic instance as key
|
|
211
|
-
const mm = new Map<RippleArray<number>, RippleArray<string>>();
|
|
180
|
+
const gg = new Mapper<
|
|
181
|
+
// key type
|
|
182
|
+
string /* value type */,
|
|
183
|
+
number
|
|
184
|
+
>();
|
|
185
|
+
// 33. Map of generic instance as key
|
|
186
|
+
const mm = new Map<RippleArray<number>, RippleArray<string>>();
|
|
187
|
+
</>;
|
|
212
188
|
}
|
|
213
189
|
|
|
214
190
|
render(App);
|
|
@@ -4,22 +4,28 @@ describe('Context API', () => {
|
|
|
4
4
|
it('handles context override in nested components', async () => {
|
|
5
5
|
const MessageContext = Context('default');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
function Inner() {
|
|
8
|
+
return <>
|
|
9
|
+
const msg = MessageContext.get();
|
|
10
|
+
<span>{msg}</span>
|
|
11
|
+
</>;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
|
|
14
|
+
function Middle() {
|
|
15
|
+
return <>
|
|
16
|
+
MessageContext.set('middle');
|
|
17
|
+
<div>
|
|
18
|
+
<Inner />
|
|
19
|
+
</div>
|
|
20
|
+
</>;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
function Outer() {
|
|
24
|
+
return <>
|
|
25
|
+
MessageContext.set('outer');
|
|
26
|
+
<Middle />
|
|
27
|
+
<Inner />
|
|
28
|
+
</>;
|
|
23
29
|
}
|
|
24
30
|
|
|
25
31
|
const { body } = await render(Outer);
|