Skip to content

Commit bf34810

Browse files
ZihanChen-MSFTfacebook-github-bot
authored andcommitted
Turbo module codegen support interface with inheritance in module (#36011)
Summary: The [previous pull request](#35812) enables defining interfaces and using them in a turbo module, but all members are flattened, this is not the best option for codegen for object oriented languages. In this pull request, an optional member `baseTypes` is added to aliased objects. Members are still flattened for backward compatibility, if a codegen doesn't care about that nothing needs to be changed. ### Example ```typescript interface A { a : string; } interface B extends A { b : number; } ``` #### Before the previous pull request `interface` is not allowed here, you must use type alias. #### At the previous pull request `interface` is allowed, but it is translated to ```typescript type A = {a : string}; type B = {a : string, b : number}; ``` #### At this pull request Extra information is provided so that you know `B` extends `A`. By comparing `B` to `A` it is easy to know that `B::a` is obtained from `A`. ## Changelog [GENERAL] [CHANGED] - Turbo module codegen support interface with inheritance in module Pull Request resolved: #36011 Test Plan: `yarn jest react-native-codegen` passed Reviewed By: rshest Differential Revision: D42882650 Pulled By: cipolleschi fbshipit-source-id: 32d502e8a99c4151fae0a1f4dfa60db9ac827963
1 parent 597a1ff commit bf34810

3 files changed

Lines changed: 84 additions & 1 deletion

File tree

packages/react-native-codegen/src/CodegenSchema.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export type VoidTypeAnnotation = $ReadOnly<{
5353
export type ObjectTypeAnnotation<+T> = $ReadOnly<{
5454
type: 'ObjectTypeAnnotation',
5555
properties: $ReadOnlyArray<NamedShape<T>>,
56+
57+
// metadata for objects that generated from interfaces
58+
baseTypes?: $ReadOnlyArray<string>,
5659
}>;
5760

5861
type FunctionTypeAnnotation<+P, +R> = $ReadOnly<{

packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,6 +1521,56 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_NE
15211521
}
15221522
]
15231523
},
1524+
'Base1': {
1525+
'type': 'ObjectTypeAnnotation',
1526+
'properties': [
1527+
{
1528+
'name': 'bar1',
1529+
'optional': false,
1530+
'typeAnnotation': {
1531+
'type': 'TypeAliasTypeAnnotation',
1532+
'name': 'Bar'
1533+
}
1534+
}
1535+
]
1536+
},
1537+
'Base2': {
1538+
'type': 'ObjectTypeAnnotation',
1539+
'properties': [
1540+
{
1541+
'name': 'bar2',
1542+
'optional': false,
1543+
'typeAnnotation': {
1544+
'type': 'TypeAliasTypeAnnotation',
1545+
'name': 'Bar'
1546+
}
1547+
}
1548+
]
1549+
},
1550+
'Base3': {
1551+
'type': 'ObjectTypeAnnotation',
1552+
'properties': [
1553+
{
1554+
'name': 'bar2',
1555+
'optional': false,
1556+
'typeAnnotation': {
1557+
'type': 'TypeAliasTypeAnnotation',
1558+
'name': 'Bar'
1559+
}
1560+
},
1561+
{
1562+
'name': 'bar3',
1563+
'optional': false,
1564+
'typeAnnotation': {
1565+
'type': 'TypeAliasTypeAnnotation',
1566+
'name': 'Bar'
1567+
}
1568+
}
1569+
],
1570+
'baseTypes': [
1571+
'Base2'
1572+
]
1573+
},
15241574
'Foo': {
15251575
'type': 'ObjectTypeAnnotation',
15261576
'properties': [
@@ -1556,6 +1606,10 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_NE
15561606
'name': 'Bar'
15571607
}
15581608
}
1609+
],
1610+
'baseTypes': [
1611+
'Base1',
1612+
'Base3'
15591613
]
15601614
}
15611615
},

packages/react-native-codegen/src/parsers/typescript/modules/index.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,26 @@ function translateTypeAnnotation(
221221
}
222222
}
223223
case 'TSInterfaceDeclaration': {
224-
const objectTypeAnnotation = {
224+
const baseTypes = (typeAnnotation.extends ?? []).map(
225+
extend => extend.expression.name,
226+
);
227+
for (const baseType of baseTypes) {
228+
// ensure base types exist and appear in aliasMap
229+
translateTypeAnnotation(
230+
hasteModuleName,
231+
{
232+
type: 'TSTypeReference',
233+
typeName: {type: 'Identifier', name: baseType},
234+
},
235+
types,
236+
aliasMap,
237+
tryParse,
238+
cxxOnly,
239+
parser,
240+
);
241+
}
242+
243+
let objectTypeAnnotation = {
225244
type: 'ObjectTypeAnnotation',
226245
// $FlowFixMe[missing-type-arg]
227246
properties: (flattenProperties(
@@ -246,8 +265,15 @@ function translateTypeAnnotation(
246265
},
247266
)
248267
.filter(Boolean),
268+
baseTypes,
249269
};
250270

271+
if (objectTypeAnnotation.baseTypes.length === 0) {
272+
// The flow checker does not allow adding a member after an object literal is created
273+
// so here I do it in a reverse way
274+
delete objectTypeAnnotation.baseTypes;
275+
}
276+
251277
return typeAliasResolution(
252278
typeAliasResolutionStatus,
253279
objectTypeAnnotation,

0 commit comments

Comments
 (0)