Allow type exports from the typed native component

Summary:
## Context
At the moment, the codegen process does not expect any types defined in a native component (*NativeComponent.js) to be exported. For example, the `NativeProps` type may be defined as:

```
// RCTSegmentedControlNativeComponent.js

type NativeProps = $ReadOnly<{|
   ...
   onChange?: ?(event: BubblingEvent<Event>) => mixed,
|}>;
```

However, it would be helpful to be able to reuse `NativeProps` in the user facing component:

```
// SegmentedControlIOS.js

type Props = $ReadOnly<{|
   ...NativeProps
  onValueChange?: ?(value: number) => mixed,
|}>;
```

## Changes
- updates the `getTypes` function to unwrap the type declaration inside exported declarations
- add test to verify that exported types are parsed as expected

Reviewed By: rickhanlonii

Differential Revision: D15851693

fbshipit-source-id: a9cd375c69cbb8fe9a38be3d2a681227444fb33d
This commit is contained in:
Cameron Bourke
2019-06-17 09:05:09 -07:00
committed by Facebook Github Bot
parent 853c667eb5
commit be07435e6a
3 changed files with 419 additions and 5 deletions
@@ -551,6 +551,45 @@ type ModuleProps = $ReadOnly<{|
export default codegenNativeComponent<ModuleProps>('Module');
`;
const PROPS_AND_EVENTS_TYPES_EXPORTED = `
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/
'use strict';
const codegenNativeComponent = require('codegenNativeComponent');
import type {
BubblingEvent,
DirectEvent,
} from 'CodegenTypes';
import type {ViewProps} from 'ViewPropTypes';
export type EventInFile = $ReadOnly<{|
${EVENT_DEFINITION}
|}>;
export type ModuleProps = $ReadOnly<{|
...ViewProps,
// No props
// Events defined inline
onBubblingEventDefinedInline: (event: BubblingEvent<EventInFile>) => void,
onDirectEventDefinedInline: (event: DirectEvent<EventInFile>) => void,
|}>;
export default codegenNativeComponent<ModuleProps>('Module');
`;
module.exports = {
ALL_PROP_TYPES_NO_EVENTS,
ARRAY_PROP_TYPES_NO_EVENTS,
@@ -559,4 +598,5 @@ module.exports = {
EVENTS_DEFINED_IN_FILE_WITH_ALL_TYPES,
EVENTS_DEFINED_AS_NULL_IN_FILE,
EVENTS_DEFINED_AS_NULL_INLINE,
PROPS_AND_EVENTS_TYPES_EXPORTED,
};
@@ -3968,3 +3968,375 @@ Object {
},
}
`;
exports[`RN Codegen Flow Parser can generate fixture PROPS_AND_EVENTS_TYPES_EXPORTED 1`] = `
Object {
"modules": Object {
"Module": Object {
"components": Object {
"Module": Object {
"events": Array [
Object {
"bubblingType": "bubble",
"name": "onBubblingEventDefinedInline",
"optional": false,
"typeAnnotation": Object {
"argument": Object {
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_key",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_value",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_both",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "string_required",
"optional": false,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_value",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_both",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "float_required",
"optional": false,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_key",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_both",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "int32_required",
"optional": false,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_key",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_value",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "object_required",
"optional": false,
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "BooleanTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_key",
"optional": true,
"properties": Array [
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_value",
"optional": true,
"properties": Array [
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_both",
"optional": true,
"properties": Array [
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_required_nested_2_layers",
"optional": false,
"properties": Array [
Object {
"name": "object_optional_nested_1_layer",
"optional": true,
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "Int32TypeAnnotation",
},
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
"type": "EventTypeAnnotation",
},
},
Object {
"bubblingType": "direct",
"name": "onDirectEventDefinedInline",
"optional": false,
"typeAnnotation": Object {
"argument": Object {
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_key",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_value",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "boolean_optional_both",
"optional": true,
"type": "BooleanTypeAnnotation",
},
Object {
"name": "string_required",
"optional": false,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_value",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "string_optional_both",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "float_required",
"optional": false,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_key",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "float_optional_both",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "int32_required",
"optional": false,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_key",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_value",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
Object {
"name": "object_required",
"optional": false,
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "BooleanTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_key",
"optional": true,
"properties": Array [
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_value",
"optional": true,
"properties": Array [
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_optional_both",
"optional": true,
"properties": Array [
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
Object {
"name": "object_required_nested_2_layers",
"optional": false,
"properties": Array [
Object {
"name": "object_optional_nested_1_layer",
"optional": true,
"properties": Array [
Object {
"name": "boolean_required",
"optional": false,
"type": "Int32TypeAnnotation",
},
Object {
"name": "string_optional_key",
"optional": true,
"type": "StringTypeAnnotation",
},
Object {
"name": "float_optional_value",
"optional": true,
"type": "FloatTypeAnnotation",
},
Object {
"name": "int32_optional_both",
"optional": true,
"type": "Int32TypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
],
"type": "ObjectTypeAnnotation",
},
"type": "EventTypeAnnotation",
},
},
],
"extendsProps": Array [
Object {
"knownTypeName": "ReactNativeCoreViewProps",
"type": "ReactNativeBuiltInType",
},
],
"props": Array [],
},
},
},
},
}
`;
+7 -5
View File
@@ -57,12 +57,14 @@ function findConfig(ast) {
}
function getTypes(ast) {
return ast.body
.filter(node => node.type === 'TypeAlias')
.reduce((types, node) => {
return ast.body.reduce((types, node) => {
if (node.type === 'ExportNamedDeclaration') {
types[node.declaration.id.name] = node.declaration;
} else if (node.type === 'TypeAlias') {
types[node.id.name] = node;
return types;
}, {});
}
return types;
}, {});
}
function getPropProperties(propsTypeName, types) {