diff --git a/packages/react-native-codegen/e2e/deep_imports/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap b/packages/react-native-codegen/e2e/deep_imports/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap index b974709b3b6..9bf2025a3a4 100644 --- a/packages/react-native-codegen/e2e/deep_imports/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap +++ b/packages/react-native-codegen/e2e/deep_imports/__tests__/modules/__snapshots__/GenerateModuleObjCpp-test.js.snap @@ -275,6 +275,9 @@ namespace JS { struct ConstantsEEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEEE; + struct Input { RCTRequired D; RCTRequired E; @@ -304,6 +307,9 @@ namespace JS { struct ConstantsEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEE; + struct Input { RCTRequired D; RCTRequired E; @@ -333,6 +339,9 @@ namespace JS { struct ConstantsE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsE; + struct Input { RCTRequired D; RCTRequired E; @@ -362,6 +371,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired D; RCTRequired E; @@ -420,6 +432,9 @@ namespace JS { struct ConstantsEEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEEE; + struct Input { std::optional D; std::optional E; @@ -449,6 +464,9 @@ namespace JS { struct ConstantsEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEE; + struct Input { std::optional D; std::optional E; @@ -478,6 +496,9 @@ namespace JS { struct ConstantsE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsE; + struct Input { std::optional D; std::optional E; @@ -507,6 +528,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional D; id _Nullable A; @@ -698,6 +722,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired const1; RCTRequired const2; @@ -768,6 +795,9 @@ namespace JS { struct ConstantsIdElement { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsIdElement; + struct Input { RCTRequired prop; }; @@ -795,6 +825,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired> const1; RCTRequired> const2; @@ -896,6 +929,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired> const1; RCTRequired> const2; @@ -996,6 +1032,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional const1; std::optional const2; @@ -1096,6 +1135,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional const1; std::optional const2; @@ -1787,6 +1829,9 @@ namespace JS { struct ConstantsEEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEEE; + struct Input { RCTRequired D; RCTRequired E; @@ -1816,6 +1861,9 @@ namespace JS { struct ConstantsEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEE; + struct Input { RCTRequired D; RCTRequired E; @@ -1845,6 +1893,9 @@ namespace JS { struct ConstantsE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsE; + struct Input { RCTRequired D; RCTRequired E; @@ -1874,6 +1925,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired D; RCTRequired E; @@ -1932,6 +1986,9 @@ namespace JS { struct ConstantsEEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEEE; + struct Input { std::optional D; std::optional E; @@ -1961,6 +2018,9 @@ namespace JS { struct ConstantsEE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsEE; + struct Input { std::optional D; std::optional E; @@ -1990,6 +2050,9 @@ namespace JS { struct ConstantsE { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsE; + struct Input { std::optional D; std::optional E; @@ -2019,6 +2082,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional D; id _Nullable A; @@ -2210,6 +2276,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired const1; RCTRequired const2; @@ -2280,6 +2349,9 @@ namespace JS { struct ConstantsIdElement { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ConstantsIdElement; + struct Input { RCTRequired prop; }; @@ -2307,6 +2379,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired> const1; RCTRequired> const2; @@ -2408,6 +2483,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired> const1; RCTRequired> const2; @@ -2508,6 +2586,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional const1; std::optional const2; @@ -2608,6 +2689,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { std::optional const1; std::optional const2; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js index f3de50ae777..d281e5c7501 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/header/serializeConstantsStruct.js @@ -35,6 +35,9 @@ const StructTemplate = ({ struct ${structName} { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = ${structName}; + struct Input { ${builderInputProps} }; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index 8d8a17e00b1..b3c18eeb73e 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -1008,6 +1008,9 @@ namespace JS { struct Constants { struct Builder { + // Backwards compat for RCTTypedModuleConstants + using ResultT = Constants; + struct Input { RCTRequired const1; RCTRequired const2; diff --git a/packages/react-native/Libraries/TypeSafety/RCTTypedModuleConstants.h b/packages/react-native/Libraries/TypeSafety/RCTTypedModuleConstants.h index d6a71e57ac9..26aeccbb303 100644 --- a/packages/react-native/Libraries/TypeSafety/RCTTypedModuleConstants.h +++ b/packages/react-native/Libraries/TypeSafety/RCTTypedModuleConstants.h @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +#include #include #import @@ -32,10 +33,44 @@ namespace facebook::react { +namespace detail { + +// Helper to detect if T is a Builder type. +// Builder types have: nested Input struct and buildUnsafeRawValue() method. +template +struct IsBuilder : std::false_type {}; + +template +struct IsBuilder().buildUnsafeRawValue())>> + : std::true_type {}; + +// Resolve Builder to its parent Constants type. +// For backwards compatibility: if T is a Builder type (e.g., JS::X::Constants::Builder), +// we resolve to the parent Constants type (JS::X::Constants). +// +// This requires Builder to have a type alias `using ResultT = Constants;` defined by codegen. +template ::value> +struct ResolveConstantsType { + // Not a Builder, use T as-is + using type = T; +}; + +// Specialization for Builder types that have ResultT defined +template +struct ResolveConstantsType { + // Use T::ResultT which points to the parent Constants type (added by codegen) + using type = typename T::ResultT; +}; + +} // namespace detail + // Objective-C doesn't allow arbitrary types in its lightweight generics, only object and block types. We can work // around that by having the struct type we care about be a block-argument. The block never exists at runtime. +// +// For backwards compatibility: if T is a Builder type (e.g., JS::Module::Constants::Builder), +// ModuleConstants resolves to the same type as ModuleConstants. template -using ModuleConstants = _RCTTypedModuleConstants *; +using ModuleConstants = _RCTTypedModuleConstants::type)> *; template ModuleConstants typedConstants(typename T::Builder::Input &&value) diff --git a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h index 12a26dbfc0d..142cdd2f474 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h +++ b/packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h @@ -25,6 +25,8 @@ NS_ASSUME_NONNULL_BEGIN namespace JS::NativeSampleTurboModule { struct Constants { struct Builder { + using ResultT = Constants; + struct Input { RCTRequired const1; RCTRequired const2;