From 3c6bf7bf32bf8ee1b648442e227cb8330c41df83 Mon Sep 17 00:00:00 2001 From: Ruslan Shestopalyuk Date: Thu, 24 Aug 2023 06:54:03 -0700 Subject: [PATCH] Suport type aliases for TM getConstants() return type (#39136) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/39136 ## Changelog: [Internal] - `getConstants()` method for TM was enforced to only use object literals for the return type specs. This limits flexibility, in particular those data structures can't be consequently exported and picked up by codegen (not even mentioning the potential need for copypasting those obejct literals around). This relaxes this restriction. Note that I've been digging into the development history in order to find out whether there was any particular historical reason for such a limitation, but couldn't find any, so I assume it was rather incidental. Reviewed By: christophpurrer Differential Revision: D48620652 fbshipit-source-id: 92d6ba531fc99fb9b25b4957ae123e7832f44ee4 --- .../generators/modules/GenerateModuleJavaSpec.js | 16 ++++++++++------ .../GenerateModuleObjCpp/serializeMethod.js | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js index 052a6d7b192..02ccc266898 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJavaSpec.js @@ -355,16 +355,20 @@ function getFalsyReturnStatementFromReturnType( function buildGetConstantsMethod( method: NativeModulePropertyShape, imports: Set, + resolveAlias: AliasResolver, ): string { const [methodTypeAnnotation] = unwrapNullable(method.typeAnnotation); - if ( - methodTypeAnnotation.returnTypeAnnotation.type === 'ObjectTypeAnnotation' - ) { + let returnTypeAnnotation = methodTypeAnnotation.returnTypeAnnotation; + if (returnTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + // The return type is an alias, resolve it to get the expected undelying object literal type + returnTypeAnnotation = resolveAlias(returnTypeAnnotation.name); + } + + if (returnTypeAnnotation.type === 'ObjectTypeAnnotation') { const requiredProps = []; const optionalProps = []; - const rawProperties = - methodTypeAnnotation.returnTypeAnnotation.properties || []; + const rawProperties = returnTypeAnnotation.properties || []; rawProperties.forEach(p => { if (p.optional || p.typeAnnotation.type === 'NullableTypeAnnotation') { optionalProps.push(p.name); @@ -470,7 +474,7 @@ module.exports = { const methods = properties.map(method => { if (method.name === 'getConstants') { - return buildGetConstantsMethod(method, imports); + return buildGetConstantsMethod(method, imports, resolveAlias); } const [methodTypeAnnotation] = diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js index 32a13879c94..9dcf621c709 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleObjCpp/serializeMethod.js @@ -459,14 +459,24 @@ function serializeConstantsProtocolMethods( ); } - const {returnTypeAnnotation} = propertyTypeAnnotation; + let {returnTypeAnnotation} = propertyTypeAnnotation; + + if (returnTypeAnnotation.type === 'TypeAliasTypeAnnotation') { + // The return type is an alias, resolve it to get the expected undelying object literal type + returnTypeAnnotation = resolveAlias(returnTypeAnnotation.name); + } + if (returnTypeAnnotation.type !== 'ObjectTypeAnnotation') { throw new Error( - `${hasteModuleName}.getConstants() may only return an object literal: {...}.`, + `${hasteModuleName}.getConstants() may only return an object literal: {...}` + + ` or a type alias of such. Got '${propertyTypeAnnotation.returnTypeAnnotation.type}'.`, ); } - if (returnTypeAnnotation.properties.length === 0) { + if ( + returnTypeAnnotation.type === 'ObjectTypeAnnotation' && + returnTypeAnnotation.properties.length === 0 + ) { return []; }