Skip to content

Support ReadOnly/Readonly wrapped custom structs in C++ TurboModule codegen#56051

Open
christophpurrer wants to merge 1 commit intofacebook:mainfrom
christophpurrer:export-D96044884
Open

Support ReadOnly/Readonly wrapped custom structs in C++ TurboModule codegen#56051
christophpurrer wants to merge 1 commit intofacebook:mainfrom
christophpurrer:export-D96044884

Conversation

@christophpurrer
Copy link
Contributor

Summary:
When parsing custom struct types in RN TurboModule flow specs for C++ (cxxOnly) codegen, the getObjectTypeAnnotations function in parsers-commons.js silently dropped types wrapped in $ReadOnly<{...}> or Readonly<{...}>.

The root cause: parser.nextNodeForTypeAlias(value) returns the raw right-hand side of a type alias. For export type Foo = Readonly<{...}>, this returns a GenericTypeAnnotation node (the Readonly<...> wrapper), not an ObjectTypeAnnotation. The existing guard check (parent.type !== 'ObjectTypeAnnotation') then rejects the type, causing it to be silently skipped from the alias map.

The fix unwraps $ReadOnly/Readonly GenericTypeAnnotation wrappers (Flow) and Readonly TSTypeReference wrappers (TypeScript) before performing the type check, then obtains properties directly from the unwrapped node.

Also updates NativeCxxModuleExample.js to use Readonly<{...}> on ConstantsStruct as a demonstration and build-time validation of the fix.

Changelog: [Internal]

Differential Revision: D96044884

@meta-codesync
Copy link

meta-codesync bot commented Mar 11, 2026

@christophpurrer has exported this pull request. If you are a Meta employee, you can view the originating Diff in D96044884.

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 11, 2026
…odegen (facebook#56051)

Summary:

When parsing custom struct types in RN TurboModule flow specs for C++ (cxxOnly) codegen, the `getObjectTypeAnnotations` function in `parsers-commons.js` silently dropped types wrapped in `$ReadOnly<{...}>` or `Readonly<{...}>`.

The root cause: `parser.nextNodeForTypeAlias(value)` returns the raw right-hand side of a type alias. For `export type Foo = Readonly<{...}>`, this returns a `GenericTypeAnnotation` node (the `Readonly<...>` wrapper), not an `ObjectTypeAnnotation`. The existing guard check (`parent.type !== 'ObjectTypeAnnotation'`) then rejects the type, causing it to be silently skipped from the alias map.

The fix unwraps `$ReadOnly`/`Readonly` `GenericTypeAnnotation` wrappers (Flow) and `Readonly` `TSTypeReference` wrappers (TypeScript) before performing the type check, then obtains properties directly from the unwrapped node.

Also updates `NativeCxxModuleExample.js` to use `Readonly<{...}>` on `ConstantsStruct` as a demonstration and build-time validation of the fix.

Changelog: [Internal]

Differential Revision: D96044884
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants