@samitouri / QOS-React / commits / c87a1916f4

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 +}