Skip to content

Commit 4c2e457

Browse files
authored
compiler: Handle TSNonNullAssertion expressions (#29218)
## Summary We ran React compiler against part of our codebase and collected compiler errors. One of the more common non-actionable errors is caused by usage of the `!` TypeScript non-null assertion operation: ``` (BuildHIR::lowerExpression) Handle TSNonNullExpression expressions ``` It seems like React Compiler _should_ be able to support this by just ignoring the syntax and using the underlying expression. I'm sure a lot of our non-null assertion usage should not exist and I understand if React Compiler does not want to support this syntax. It wasn't obvious to me if this omission was intentional or if there are future plans to use `TSNonNullExpression` as part of the compiler's analysis. If there are no future plans it seems like just ignoring it should be fine. ## How did you test this change? ```sh ❯ yarn snap --filter yarn run v1.17.3 $ yarn workspace babel-plugin-react-compiler run snap --filter $ node ../snap/dist/main.js --filter PASS non-null-assertion 1 Tests, 1 Passed, 0 Failed ```
1 parent f994737 commit 4c2e457

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2407,6 +2407,10 @@ function lowerExpression(
24072407
loc: expr.node.loc ?? GeneratedSource,
24082408
};
24092409
}
2410+
case "TSNonNullExpression": {
2411+
let expr = exprPath as NodePath<t.TSNonNullExpression>;
2412+
return lowerExpression(builder, expr.get("expression"));
2413+
}
24102414
default: {
24112415
builder.errors.push({
24122416
reason: `(BuildHIR::lowerExpression) Handle ${exprPath.type} expressions`,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
## Input
3+
4+
```javascript
5+
interface ComponentProps {
6+
name?: string;
7+
}
8+
9+
function Component(props: ComponentProps) {
10+
return props.name!.toUpperCase();
11+
}
12+
13+
export const FIXTURE_ENTRYPOINT = {
14+
fn: Component,
15+
params: [{ name: "Alice" }],
16+
};
17+
18+
```
19+
20+
## Code
21+
22+
```javascript
23+
import { c as _c } from "react/compiler-runtime";
24+
interface ComponentProps {
25+
name?: string;
26+
}
27+
28+
function Component(props) {
29+
const $ = _c(2);
30+
let t0;
31+
if ($[0] !== props.name) {
32+
t0 = props.name.toUpperCase();
33+
$[0] = props.name;
34+
$[1] = t0;
35+
} else {
36+
t0 = $[1];
37+
}
38+
return t0;
39+
}
40+
41+
export const FIXTURE_ENTRYPOINT = {
42+
fn: Component,
43+
params: [{ name: "Alice" }],
44+
};
45+
46+
```
47+
48+
### Eval output
49+
(kind: ok) "ALICE"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
interface ComponentProps {
2+
name?: string;
3+
}
4+
5+
function Component(props: ComponentProps) {
6+
return props.name!.toUpperCase();
7+
}
8+
9+
export const FIXTURE_ENTRYPOINT = {
10+
fn: Component,
11+
params: [{ name: "Alice" }],
12+
};

0 commit comments

Comments
 (0)