Skip to content

Commit ef4bc8b

Browse files
feat(babel-plugin-react-compiler): support satisfies operator (#32742)
Solve #29818 --------- Co-authored-by: Rodrigo Faria <[email protected]>
1 parent 8039f1b commit ef4bc8b

File tree

7 files changed

+176
-7
lines changed

7 files changed

+176
-7
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts

+14
Original file line numberDiff line numberDiff line change
@@ -2406,6 +2406,19 @@ function lowerExpression(
24062406
kind: 'TypeCastExpression',
24072407
value: lowerExpressionToTemporary(builder, expr.get('expression')),
24082408
typeAnnotation: typeAnnotation.node,
2409+
typeAnnotationKind: 'cast',
2410+
type: lowerType(typeAnnotation.node),
2411+
loc: exprLoc,
2412+
};
2413+
}
2414+
case 'TSSatisfiesExpression': {
2415+
let expr = exprPath as NodePath<t.TSSatisfiesExpression>;
2416+
const typeAnnotation = expr.get('typeAnnotation');
2417+
return {
2418+
kind: 'TypeCastExpression',
2419+
value: lowerExpressionToTemporary(builder, expr.get('expression')),
2420+
typeAnnotation: typeAnnotation.node,
2421+
typeAnnotationKind: 'satisfies',
24092422
type: lowerType(typeAnnotation.node),
24102423
loc: exprLoc,
24112424
};
@@ -2417,6 +2430,7 @@ function lowerExpression(
24172430
kind: 'TypeCastExpression',
24182431
value: lowerExpressionToTemporary(builder, expr.get('expression')),
24192432
typeAnnotation: typeAnnotation.node,
2433+
typeAnnotationKind: 'as',
24202434
type: lowerType(typeAnnotation.node),
24212435
loc: exprLoc,
24222436
};

compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -910,13 +910,21 @@ export type InstructionValue =
910910
value: Place;
911911
loc: SourceLocation;
912912
}
913-
| {
913+
| ({
914914
kind: 'TypeCastExpression';
915915
value: Place;
916-
typeAnnotation: t.FlowType | t.TSType;
917916
type: Type;
918917
loc: SourceLocation;
919-
}
918+
} & (
919+
| {
920+
typeAnnotation: t.FlowType;
921+
typeAnnotationKind: 'cast';
922+
}
923+
| {
924+
typeAnnotation: t.TSType;
925+
typeAnnotationKind: 'as' | 'satisfies';
926+
}
927+
))
920928
| JsxExpression
921929
| {
922930
kind: 'ObjectExpression';

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -2115,10 +2115,17 @@ function codegenInstructionValue(
21152115
}
21162116
case 'TypeCastExpression': {
21172117
if (t.isTSType(instrValue.typeAnnotation)) {
2118-
value = t.tsAsExpression(
2119-
codegenPlaceToExpression(cx, instrValue.value),
2120-
instrValue.typeAnnotation,
2121-
);
2118+
if (instrValue.typeAnnotationKind === 'satisfies') {
2119+
value = t.tsSatisfiesExpression(
2120+
codegenPlaceToExpression(cx, instrValue.value),
2121+
instrValue.typeAnnotation,
2122+
);
2123+
} else {
2124+
value = t.tsAsExpression(
2125+
codegenPlaceToExpression(cx, instrValue.value),
2126+
instrValue.typeAnnotation,
2127+
);
2128+
}
21222129
} else {
21232130
value = t.typeCastExpression(
21242131
codegenPlaceToExpression(cx, instrValue.value),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @enableUseTypeAnnotations
6+
function Component(props: {id: number}) {
7+
const x = makeArray(props.id) satisfies number[];
8+
const y = x.at(0);
9+
return y;
10+
}
11+
12+
function makeArray<T>(x: T): Array<T> {
13+
return [x];
14+
}
15+
16+
export const FIXTURE_ENTRYPOINT = {
17+
fn: Component,
18+
params: [{id: 42}],
19+
};
20+
21+
```
22+
23+
## Code
24+
25+
```javascript
26+
import { c as _c } from "react/compiler-runtime"; // @enableUseTypeAnnotations
27+
function Component(props) {
28+
const $ = _c(4);
29+
let t0;
30+
if ($[0] !== props.id) {
31+
t0 = makeArray(props.id);
32+
$[0] = props.id;
33+
$[1] = t0;
34+
} else {
35+
t0 = $[1];
36+
}
37+
const x = t0 satisfies number[];
38+
let t1;
39+
if ($[2] !== x) {
40+
t1 = x.at(0);
41+
$[2] = x;
42+
$[3] = t1;
43+
} else {
44+
t1 = $[3];
45+
}
46+
const y = t1;
47+
return y;
48+
}
49+
50+
function makeArray(x) {
51+
const $ = _c(2);
52+
let t0;
53+
if ($[0] !== x) {
54+
t0 = [x];
55+
$[0] = x;
56+
$[1] = t0;
57+
} else {
58+
t0 = $[1];
59+
}
60+
return t0;
61+
}
62+
63+
export const FIXTURE_ENTRYPOINT = {
64+
fn: Component,
65+
params: [{ id: 42 }],
66+
};
67+
68+
```
69+
70+
### Eval output
71+
(kind: ok) 42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// @enableUseTypeAnnotations
2+
function Component(props: {id: number}) {
3+
const x = makeArray(props.id) satisfies number[];
4+
const y = x.at(0);
5+
return y;
6+
}
7+
8+
function makeArray<T>(x: T): Array<T> {
9+
return [x];
10+
}
11+
12+
export const FIXTURE_ENTRYPOINT = {
13+
fn: Component,
14+
params: [{id: 42}],
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @enableUseTypeAnnotations
6+
import {identity} from 'shared-runtime';
7+
8+
function Component(props: {id: number}) {
9+
const x = identity(props.id);
10+
const y = x satisfies number;
11+
return y;
12+
}
13+
14+
export const FIXTURE_ENTRYPOINT = {
15+
fn: Component,
16+
params: [{id: 42}],
17+
};
18+
19+
```
20+
21+
## Code
22+
23+
```javascript
24+
// @enableUseTypeAnnotations
25+
import { identity } from "shared-runtime";
26+
27+
function Component(props) {
28+
const x = identity(props.id);
29+
const y = x satisfies number;
30+
return y;
31+
}
32+
33+
export const FIXTURE_ENTRYPOINT = {
34+
fn: Component,
35+
params: [{ id: 42 }],
36+
};
37+
38+
```
39+
40+
### Eval output
41+
(kind: ok) 42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @enableUseTypeAnnotations
2+
import {identity} from 'shared-runtime';
3+
4+
function Component(props: {id: number}) {
5+
const x = identity(props.id);
6+
const y = x satisfies number;
7+
return y;
8+
}
9+
10+
export const FIXTURE_ENTRYPOINT = {
11+
fn: Component,
12+
params: [{id: 42}],
13+
};

0 commit comments

Comments
 (0)