Skip to content

Commit

Permalink
Fix interface support in turbo module TypeScript codegen (component o…
Browse files Browse the repository at this point in the history
…nly) (#34778)

Summary:
Interface was supported in component, but it only allows interfaces in limited cases.

In this change, I extended interface support to all places where object literal type is supported.

I also refactor the code so that properties and events are able to share the same implementation.

In order not to mess up the diff, I noticed that implementations are repeated in processing array properties and non-array properties. But I leave it without refactoring. I will do it in future PRs.

I also commented potential problems I found in the code.

## Changelog

[General] [Changed] - Fix interface support in turbo module TypeScript codegen (component only)

Pull Request resolved: #34778

Test Plan: `yarn jest react-native-codegen` passed

Reviewed By: cortinico

Differential Revision: D39809230

Pulled By: cipolleschi

fbshipit-source-id: cfb51ce915249b5abceafee1c08b7e5762d03519
  • Loading branch information
ZihanChen-MSFT authored and facebook-github-bot committed Sep 27, 2022
1 parent e78a495 commit 8dc6bec
Show file tree
Hide file tree
Showing 6 changed files with 483 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ const flowSnaps = require('../../../../src/parsers/flow/components/__tests__/__s
const flowExtraCases = [];
const tsFixtures = require('../../typescript/components/__test_fixtures__/fixtures.js');
const tsSnaps = require('../../../../src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap');
const tsExtraCases = ['ARRAY2_PROP_TYPES_NO_EVENTS', 'ARRAY2_STATE_TYPES'];
const tsExtraCases = [
'ARRAY2_PROP_TYPES_NO_EVENTS',
'ARRAY2_STATE_TYPES',
'PROPS_AND_EVENTS_WITH_INTERFACES',
];
const ignoredCases = ['ARRAY_PROP_TYPES_NO_EVENTS', 'ARRAY_STATE_TYPES'];

compareSnaps(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,49 @@ export default codegenNativeComponent<ModuleProps>(
) as NativeType;
`;

const PROPS_AND_EVENTS_WITH_INTERFACES = `
import type {
BubblingEventHandler,
DirectEventHandler,
Int32,
} from 'CodegenTypes';
import type {ViewProps} from 'ViewPropTypes';
import type {HostComponent} from 'react-native';
const codegenNativeComponent = require('codegenNativeComponent');
export interface Base1 {
readonly x: string;
}
export interface Base2 {
readonly y: Int32;
}
export interface Derived extends Base1, Base2 {
readonly z: boolean;
}
export interface ModuleProps extends ViewProps {
// Props
ordinary_prop: Derived;
readonly_prop: Readonly<Derived>;
ordinary_array_prop?: readonly Derived[];
readonly_array_prop?: readonly Readonly<Derived>[];
ordinary_nested_array_prop?: readonly Derived[][];
readonly_nested_array_prop?: readonly Readonly<Derived>[][];
// Events
onDirect: DirectEventHandler<Derived>;
onBubbling: BubblingEventHandler<Readonly<Derived>>;
}
export default codegenNativeComponent<ModuleProps>('Module', {
interfaceOnly: true,
paperComponentName: 'RCTModule',
}) as HostComponent<ModuleProps>;
`;

// === STATE ===
const ALL_STATE_TYPES = `
/**
Expand Down Expand Up @@ -1630,6 +1673,7 @@ module.exports = {
COMMANDS_DEFINED_WITH_ALL_TYPES,
PROPS_AS_EXTERNAL_TYPES,
COMMANDS_WITH_EXTERNAL_TYPES,
PROPS_AND_EVENTS_WITH_INTERFACES,
ALL_STATE_TYPES,
ARRAY_STATE_TYPES,
ARRAY2_STATE_TYPES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12640,6 +12640,317 @@ exports[`RN Codegen TypeScript Parser can generate fixture PROPS_AND_EVENTS_TYPE
}"
`;

exports[`RN Codegen TypeScript Parser can generate fixture PROPS_AND_EVENTS_WITH_INTERFACES 1`] = `
"{
'modules': {
'Module': {
'type': 'Component',
'components': {
'Module': {
'interfaceOnly': true,
'paperComponentName': 'RCTModule',
'extendsProps': [
{
'type': 'ReactNativeBuiltInType',
'knownTypeName': 'ReactNativeCoreViewProps'
}
],
'events': [
{
'name': 'onDirect',
'optional': false,
'bubblingType': 'direct',
'typeAnnotation': {
'type': 'EventTypeAnnotation',
'argument': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation'
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation'
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation'
}
}
]
}
}
},
{
'name': 'onBubbling',
'optional': false,
'bubblingType': 'bubble',
'typeAnnotation': {
'type': 'EventTypeAnnotation',
'argument': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation'
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation'
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation'
}
}
]
}
}
}
],
'props': [
{
'name': 'ordinary_prop',
'optional': false,
'typeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
},
{
'name': 'readonly_prop',
'optional': false,
'typeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
},
{
'name': 'ordinary_array_prop',
'optional': true,
'typeAnnotation': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
}
},
{
'name': 'readonly_array_prop',
'optional': true,
'typeAnnotation': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
}
},
{
'name': 'ordinary_nested_array_prop',
'optional': true,
'typeAnnotation': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
}
}
},
{
'name': 'readonly_nested_array_prop',
'optional': true,
'typeAnnotation': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ArrayTypeAnnotation',
'elementType': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'x',
'optional': false,
'typeAnnotation': {
'type': 'StringTypeAnnotation',
'default': null
}
},
{
'name': 'y',
'optional': false,
'typeAnnotation': {
'type': 'Int32TypeAnnotation',
'default': 0
}
},
{
'name': 'z',
'optional': false,
'typeAnnotation': {
'type': 'BooleanTypeAnnotation',
'default': false
}
}
]
}
}
}
}
],
'commands': []
}
}
}
}
}"
`;

exports[`RN Codegen TypeScript Parser can generate fixture PROPS_AS_EXTERNAL_TYPES 1`] = `
"{
'modules': {
Expand Down
Loading

0 comments on commit 8dc6bec

Please sign in to comment.