Skip to content

Commit

Permalink
Add Map / indexed object support for TypeScript parser (#35098)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #35098

Changelog:
[General][Fixed] [react-native-codegen] react-native-codegen : Add Map / indexed object support for TypeScript parser

In flow we can expose Maps via the following syntax in TM specs

`
+getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number};
`

In TypeScript writing the same spec:

`
readonly getMap: (arg: { [key: string]: number | null; }) => { [key: string]: number | null; };
`

leads to an exception the TypeScript code-gen parser

```UnsupportedObjectPropertyTypeAnnotationParserError: Module NativeTurboModuleCxx: 'ObjectTypeAnnotation' cannot contain 'TSIndexSignature'.
    at react-native-github/packages/react-native-codegen/src/parsers/typescript/modules/index.js:309:23```
```
This change fixes the TypeScript parser

Differential Revision: D40753368

fbshipit-source-id: c8ad66eb9a16cb55eee2f228e0485e1315eb443e
  • Loading branch information
christophpurrer authored and facebook-github-bot committed Oct 27, 2022
1 parent 475310d commit 354f637
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ export interface Spec extends TurboModule {
+getCallback: () => () => void;
+getMixed: (arg: mixed) => mixed;
+getEnums: (quality: Quality, resolution?: Resolution, floppy: Floppy, stringOptions: StringOptions) => string;
+getMap: (arg: {[key: string]: ?number}) => {[key: string]: ?number};
+getUnion: (chooseInt: ChooseInt, chooseFloat: ChooseFloat, chooseObject: ChooseObject, chooseString: ChooseString) => ChooseObject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,49 @@ exports[`RN Codegen Flow Parser can generate fixture CXX_ONLY_NATIVE_MODULE 1`]
]
}
},
{
'name': 'getMap',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'key',
'optional': false,
'typeAnnotation': {
'type': 'NullableTypeAnnotation',
'typeAnnotation': {
'type': 'NumberTypeAnnotation'
}
}
}
]
},
'params': [
{
'name': 'arg',
'optional': false,
'typeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'key',
'optional': false,
'typeAnnotation': {
'type': 'NullableTypeAnnotation',
'typeAnnotation': {
'type': 'NumberTypeAnnotation'
}
}
}
]
}
}
]
}
},
{
'name': 'getUnion',
'optional': false,
Expand Down
28 changes: 24 additions & 4 deletions packages/react-native-codegen/src/parsers/flow/modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,17 @@ function translateTypeAnnotation(
const objectTypeAnnotation = {
type: 'ObjectTypeAnnotation',
// $FlowFixMe[missing-type-arg]
properties: (typeAnnotation.properties: Array<$FlowFixMe>)
properties: ([
...typeAnnotation.properties,
...typeAnnotation.indexers,
]: Array<$FlowFixMe>)
.map<?NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>>(
property => {
return tryParse(() => {
if (property.type !== 'ObjectTypeProperty') {
if (
property.type !== 'ObjectTypeProperty' &&
property.type !== 'ObjectTypeIndexer'
) {
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
hasteModuleName,
property,
Expand All @@ -301,7 +307,21 @@ function translateTypeAnnotation(
);
}

const {optional, key} = property;
const {optional = false} = property;
const name =
property.type === 'ObjectTypeProperty'
? property.key.name
: property.type === 'ObjectTypeIndexer'
? 'key'
: null;
if (!name) {
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
hasteModuleName,
property,
property.type,
language,
);
}

const [propertyTypeAnnotation, isPropertyNullable] =
unwrapNullable(
Expand Down Expand Up @@ -329,7 +349,7 @@ function translateTypeAnnotation(
);
} else {
return {
name: key.name,
name,
optional,
typeAnnotation: wrapNullable(
isPropertyNullable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,7 @@ export interface Spec extends TurboModule {
readonly getCallback: () => () => void;
readonly getMixed: (arg: unknown) => unknown;
readonly getEnums: (quality: Quality, resolution?: Resolution, floppy: Floppy, stringOptions: StringOptions) => string;
readonly getMap: (arg: {[key: string]: number | null;}) => {[key: string]: number | null;};
readonly getUnion: (chooseInt: ChooseInt, chooseFloat: ChooseFloat, chooseObject: ChooseObject, chooseString: ChooseString) => ChooseObject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,49 @@ exports[`RN Codegen TypeScript Parser can generate fixture CXX_ONLY_NATIVE_MODUL
]
}
},
{
'name': 'getMap',
'optional': false,
'typeAnnotation': {
'type': 'FunctionTypeAnnotation',
'returnTypeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'key',
'optional': false,
'typeAnnotation': {
'type': 'NullableTypeAnnotation',
'typeAnnotation': {
'type': 'NumberTypeAnnotation'
}
}
}
]
},
'params': [
{
'name': 'arg',
'optional': false,
'typeAnnotation': {
'type': 'ObjectTypeAnnotation',
'properties': [
{
'name': 'key',
'optional': false,
'typeAnnotation': {
'type': 'NullableTypeAnnotation',
'typeAnnotation': {
'type': 'NumberTypeAnnotation'
}
}
}
]
}
}
]
}
},
{
'name': 'getUnion',
'optional': false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,10 @@ function translateTypeAnnotation(
.map<?NamedShape<Nullable<NativeModuleBaseTypeAnnotation>>>(
property => {
return tryParse(() => {
if (property.type !== 'TSPropertySignature') {
if (
property.type !== 'TSPropertySignature' &&
property.type !== 'TSIndexSignature'
) {
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
hasteModuleName,
property,
Expand All @@ -314,7 +317,21 @@ function translateTypeAnnotation(
);
}

const {optional = false, key} = property;
const {optional = false} = property;
const name =
property.type === 'TSPropertySignature'
? property.key.name
: property.type === 'TSIndexSignature'
? 'key'
: null;
if (!name) {
throw new UnsupportedObjectPropertyTypeAnnotationParserError(
hasteModuleName,
property,
property.type,
language,
);
}

const [propertyTypeAnnotation, isPropertyNullable] =
unwrapNullable(
Expand Down Expand Up @@ -342,7 +359,7 @@ function translateTypeAnnotation(
);
} else {
return {
name: key.name,
name,
optional,
typeAnnotation: wrapNullable(
isPropertyNullable,
Expand Down

0 comments on commit 354f637

Please sign in to comment.