Infer property types for destructuring
Joe Savona committed
May 24, 2023 at 09:54 UTC
c87a1916f435f36efa8873ddfc8e13a25d91c118
3 files changed
+86
-1
compiler/forget/src/TypeInference/InferTypes.ts
+31
-1
@@ -201,9 +201,39 @@ function* generateInstructionTypes(
201
break;
202
}
203
204
+ case "Destructure": {
205
+ const pattern = value.lvalue.pattern;
206
+ if (pattern.kind === "ArrayPattern") {
207
+ for (let i = 0; i < pattern.items.length; i++) {
208
+ const item = pattern.items[i];
209
+ if (item.kind === "Identifier") {
210
+ // To simulate tuples we use properties with `String(<index>)`, eg "0".
211
+ const propertyName = String(i);
212
+ yield equation(item.identifier.type, {
213
+ kind: "Property",
214
+ object: value.value.identifier.type,
215
+ propertyName,
216
+ });
217
+ } else {
218
+ break;
219
+ }
220
+ }
221
+ } else {
222
+ for (const property of pattern.properties) {
223
+ if (property.kind === "ObjectProperty") {
224
+ yield equation(property.place.identifier.type, {
225
+ kind: "Property",
226
+ object: value.value.identifier.type,
227
+ propertyName: property.name,
228
+ });
229
+ }
230
+ }
231
+ }
232
+ break;
233
+ }
234
+
235
case "DeclareLocal":
236
case "DeclareContext":
206
- case "Destructure":
237
case "NewExpression":
238
case "TypeCastExpression":
239
case "JsxExpression":
compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.expect.md
new
+48
@@ -0,0 +1,48 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+function Component(props) {
6
+ const x = [];
7
+ x.push(props.value);
8
+ const { length: y } = x;
9
+ foo(y);
10
+ return [x, y];
11
+}
12
+
13
+```
14
+
15
+## Code
16
+
17
+```javascript
18
+import { unstable_useMemoCache as useMemoCache } from "react";
19
+function Component(props) {
20
+ const $ = useMemoCache(5);
21
+ const c_0 = $[0] !== props.value;
22
+ let x;
23
+ if (c_0) {
24
+ x = [];
25
+ x.push(props.value);
26
+ $[0] = props.value;
27
+ $[1] = x;
28
+ } else {
29
+ x = $[1];
30
+ }
31
+ const { length: y } = x;
32
+ foo(y);
33
+ const c_2 = $[2] !== x;
34
+ const c_3 = $[3] !== y;
35
+ let t0;
36
+ if (c_2 || c_3) {
37
+ t0 = [x, y];
38
+ $[2] = x;
39
+ $[3] = y;
40
+ $[4] = t0;
41
+ } else {
42
+ t0 = $[4];
43
+ }
44
+ return t0;
45
+}
46
+
47
+```
48
+
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/compiler/destructuring-property-inference.js
new
+7
@@ -0,0 +1,7 @@
1
+function Component(props) {
2
+ const x = [];
3
+ x.push(props.value);
4
+ const { length: y } = x;
5
+ foo(y);
6
+ return [x, y];
7
+}