diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js index 66c9313a9e4..2483b6ca911 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-commons-test.js @@ -17,22 +17,17 @@ import { parseObjectProperty, wrapNullable, unwrapNullable, - emitUnionTypeAnnotation, } from '../parsers-commons'; import type {ParserType} from '../errors'; -import type {UnionTypeAnnotationMemberType} from '../../CodegenSchema'; const { - UnsupportedUnionTypeAnnotationParserError, UnsupportedObjectPropertyTypeAnnotationParserError, } = require('../errors'); import {MockedParser} from '../parserMock'; import {TypeScriptParser} from '../typescript/parser'; -import {FlowParser} from '../flow/parser'; const parser = new MockedParser(); -const flowParser = new FlowParser(); const typeScriptParser = new TypeScriptParser(); const flowTranslateTypeAnnotation = require('../flow/modules/index'); @@ -396,430 +391,3 @@ describe('parseObjectProperty', () => { }); }); }); - -describe('emitUnionTypeAnnotation', () => { - const hasteModuleName = 'SampleTurboModule'; - - describe('when language is flow', () => { - describe('when members type is numeric', () => { - const typeAnnotation = { - type: 'UnionTypeAnnotation', - types: [ - {type: 'NumberLiteralTypeAnnotation'}, - {type: 'NumberLiteralTypeAnnotation'}, - ], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'NumberTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'NumberTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is string', () => { - const typeAnnotation = { - type: 'UnionTypeAnnotation', - types: [ - {type: 'StringLiteralTypeAnnotation'}, - {type: 'StringLiteralTypeAnnotation'}, - ], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is object', () => { - const typeAnnotation = { - type: 'UnionTypeAnnotation', - types: [{type: 'ObjectTypeAnnotation'}, {type: 'ObjectTypeAnnotation'}], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'ObjectTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - flowParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'ObjectTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is mixed', () => { - const typeAnnotation = { - type: 'UnionTypeAnnotation', - types: [ - {type: 'NumberLiteralTypeAnnotation'}, - {type: 'StringLiteralTypeAnnotation'}, - {type: 'ObjectTypeAnnotation'}, - ], - }; - const unionTypes: UnionTypeAnnotationMemberType[] = [ - 'NumberTypeAnnotation', - 'StringTypeAnnotation', - 'ObjectTypeAnnotation', - ]; - describe('when nullable is true', () => { - it('throws an excpetion', () => { - const expected = new UnsupportedUnionTypeAnnotationParserError( - hasteModuleName, - typeAnnotation, - unionTypes, - flowParser.language(), - ); - - expect(() => { - emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - flowParser, - ); - }).toThrow(expected); - }); - }); - - describe('when nullable is false', () => { - it('throws an excpetion', () => { - const expected = new UnsupportedUnionTypeAnnotationParserError( - hasteModuleName, - typeAnnotation, - unionTypes, - flowParser.language(), - ); - - expect(() => { - emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - flowParser, - ); - }).toThrow(expected); - }); - }); - }); - }); - - describe('when language is typescript', () => { - describe('when members type is numeric', () => { - const typeAnnotation = { - type: 'TSUnionType', - types: [ - { - type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, - }, - { - type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, - }, - ], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'NumberTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'NumberTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is string', () => { - const typeAnnotation = { - type: 'TSUnionType', - types: [ - { - type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, - }, - { - type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, - }, - ], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'StringTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is object', () => { - const typeAnnotation = { - type: 'TSUnionType', - types: [ - { - type: 'TSLiteralType', - }, - { - type: 'TSLiteralType', - }, - ], - }; - describe('when nullable is true', () => { - it('returns nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'NullableTypeAnnotation', - typeAnnotation: { - type: 'UnionTypeAnnotation', - memberType: 'ObjectTypeAnnotation', - }, - }; - - expect(result).toEqual(expected); - }); - }); - - describe('when nullable is false', () => { - it('returns non nullable type annotation', () => { - const result = emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - - const expected = { - type: 'UnionTypeAnnotation', - memberType: 'ObjectTypeAnnotation', - }; - - expect(result).toEqual(expected); - }); - }); - }); - - describe('when members type is mixed', () => { - const typeAnnotation = { - type: 'TSUnionType', - types: [ - { - type: 'TSLiteralType', - literal: {type: 'NumericLiteral'}, - }, - { - type: 'TSLiteralType', - literal: {type: 'StringLiteral'}, - }, - { - type: 'TSLiteralType', - }, - ], - }; - const unionTypes = [ - 'NumberTypeAnnotation', - 'StringTypeAnnotation', - 'ObjectTypeAnnotation', - ]; - describe('when nullable is true', () => { - it('throws an excpetion', () => { - const expected = new UnsupportedUnionTypeAnnotationParserError( - hasteModuleName, - typeAnnotation, - unionTypes, - typeScriptParser.language(), - ); - - expect(() => { - emitUnionTypeAnnotation( - true, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - }).toThrow(expected); - }); - }); - - describe('when nullable is false', () => { - it('throws an excpetion', () => { - const expected = new UnsupportedUnionTypeAnnotationParserError( - hasteModuleName, - typeAnnotation, - unionTypes, - typeScriptParser.language(), - ); - - expect(() => { - emitUnionTypeAnnotation( - false, - hasteModuleName, - typeAnnotation, - typeScriptParser, - ); - }).toThrow(expected); - }); - }); - }); - }); -}); diff --git a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js index b55fa616a5f..9f17748593d 100644 --- a/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js +++ b/packages/react-native-codegen/src/parsers/__tests__/parsers-primitives-test.js @@ -11,6 +11,8 @@ 'use-strict'; +import type {UnionTypeAnnotationMemberType} from '../../CodegenSchema'; + const { emitBoolean, emitDouble, @@ -23,12 +25,18 @@ const { emitVoid, emitString, emitStringish, - emitMixedTypeAnnotation, + emitMixed, typeAliasResolution, } = require('../parsers-primitives.js'); -import {MockedParser} from '../parserMock'; +const {MockedParser} = require('../parserMock'); +const {emitUnion} = require('../parsers-primitives'); +const {UnsupportedUnionTypeAnnotationParserError} = require('../errors'); +const {FlowParser} = require('../flow/parser'); +const {TypeScriptParser} = require('../typescript/parser'); const parser = new MockedParser(); +const flowParser = new FlowParser(); +const typeScriptParser = new TypeScriptParser(); describe('emitBoolean', () => { describe('when nullable is true', () => { @@ -472,10 +480,10 @@ describe('emitObject', () => { }); }); -describe('emitMixedTypeAnnotation', () => { +describe('emitMixed', () => { describe('when nullable is true', () => { it('returns nullable type annotation', () => { - const result = emitMixedTypeAnnotation(true); + const result = emitMixed(true); const expected = { type: 'NullableTypeAnnotation', typeAnnotation: { @@ -488,7 +496,7 @@ describe('emitMixedTypeAnnotation', () => { }); describe('when nullable is false', () => { it('returns non nullable type annotation', () => { - const result = emitMixedTypeAnnotation(false); + const result = emitMixed(false); const expected = { type: 'MixedTypeAnnotation', }; @@ -497,3 +505,410 @@ describe('emitMixedTypeAnnotation', () => { }); }); }); + +describe('emitUnion', () => { + const hasteModuleName = 'SampleTurboModule'; + + describe('when language is flow', () => { + describe('when members type is numeric', () => { + const typeAnnotation = { + type: 'UnionTypeAnnotation', + types: [ + {type: 'NumberLiteralTypeAnnotation'}, + {type: 'NumberLiteralTypeAnnotation'}, + ], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'NumberTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'NumberTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is string', () => { + const typeAnnotation = { + type: 'UnionTypeAnnotation', + types: [ + {type: 'StringLiteralTypeAnnotation'}, + {type: 'StringLiteralTypeAnnotation'}, + ], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'StringTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'StringTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is object', () => { + const typeAnnotation = { + type: 'UnionTypeAnnotation', + types: [{type: 'ObjectTypeAnnotation'}, {type: 'ObjectTypeAnnotation'}], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'ObjectTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + flowParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'ObjectTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is mixed', () => { + const typeAnnotation = { + type: 'UnionTypeAnnotation', + types: [ + {type: 'NumberLiteralTypeAnnotation'}, + {type: 'StringLiteralTypeAnnotation'}, + {type: 'ObjectTypeAnnotation'}, + ], + }; + const unionTypes: UnionTypeAnnotationMemberType[] = [ + 'NumberTypeAnnotation', + 'StringTypeAnnotation', + 'ObjectTypeAnnotation', + ]; + describe('when nullable is true', () => { + it('throws an excpetion', () => { + const expected = new UnsupportedUnionTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + unionTypes, + flowParser.language(), + ); + + expect(() => { + emitUnion(true, hasteModuleName, typeAnnotation, flowParser); + }).toThrow(expected); + }); + }); + + describe('when nullable is false', () => { + it('throws an excpetion', () => { + const expected = new UnsupportedUnionTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + unionTypes, + flowParser.language(), + ); + + expect(() => { + emitUnion(false, hasteModuleName, typeAnnotation, flowParser); + }).toThrow(expected); + }); + }); + }); + }); + + describe('when language is typescript', () => { + describe('when members type is numeric', () => { + const typeAnnotation = { + type: 'TSUnionType', + types: [ + { + type: 'TSLiteralType', + literal: {type: 'NumericLiteral'}, + }, + { + type: 'TSLiteralType', + literal: {type: 'NumericLiteral'}, + }, + ], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'NumberTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'NumberTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is string', () => { + const typeAnnotation = { + type: 'TSUnionType', + types: [ + { + type: 'TSLiteralType', + literal: {type: 'StringLiteral'}, + }, + { + type: 'TSLiteralType', + literal: {type: 'StringLiteral'}, + }, + ], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'StringTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'StringTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is object', () => { + const typeAnnotation = { + type: 'TSUnionType', + types: [ + { + type: 'TSLiteralType', + }, + { + type: 'TSLiteralType', + }, + ], + }; + describe('when nullable is true', () => { + it('returns nullable type annotation', () => { + const result = emitUnion( + true, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'NullableTypeAnnotation', + typeAnnotation: { + type: 'UnionTypeAnnotation', + memberType: 'ObjectTypeAnnotation', + }, + }; + + expect(result).toEqual(expected); + }); + }); + + describe('when nullable is false', () => { + it('returns non nullable type annotation', () => { + const result = emitUnion( + false, + hasteModuleName, + typeAnnotation, + typeScriptParser, + ); + + const expected = { + type: 'UnionTypeAnnotation', + memberType: 'ObjectTypeAnnotation', + }; + + expect(result).toEqual(expected); + }); + }); + }); + + describe('when members type is mixed', () => { + const typeAnnotation = { + type: 'TSUnionType', + types: [ + { + type: 'TSLiteralType', + literal: {type: 'NumericLiteral'}, + }, + { + type: 'TSLiteralType', + literal: {type: 'StringLiteral'}, + }, + { + type: 'TSLiteralType', + }, + ], + }; + const unionTypes = [ + 'NumberTypeAnnotation', + 'StringTypeAnnotation', + 'ObjectTypeAnnotation', + ]; + describe('when nullable is true', () => { + it('throws an excpetion', () => { + const expected = new UnsupportedUnionTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + unionTypes, + typeScriptParser.language(), + ); + + expect(() => { + emitUnion(true, hasteModuleName, typeAnnotation, typeScriptParser); + }).toThrow(expected); + }); + }); + + describe('when nullable is false', () => { + it('throws an excpetion', () => { + const expected = new UnsupportedUnionTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + unionTypes, + typeScriptParser.language(), + ); + + expect(() => { + emitUnion(false, hasteModuleName, typeAnnotation, typeScriptParser); + }).toThrow(expected); + }); + }); + }); + }); +}); diff --git a/packages/react-native-codegen/src/parsers/flow/modules/index.js b/packages/react-native-codegen/src/parsers/flow/modules/index.js index 00e13afcf81..125e532ea6a 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -28,7 +28,6 @@ const { wrapNullable, assertGenericTypeAnnotationHasExactlyOneTypeParameter, parseObjectProperty, - emitUnionTypeAnnotation, translateDefault, buildPropertySchema, } = require('../../parsers-commons'); @@ -45,7 +44,8 @@ const { emitVoid, emitString, emitStringish, - emitMixedTypeAnnotation, + emitMixed, + emitUnion, typeAliasResolution, translateArrayTypeAnnotation, } = require('../../parsers-primitives'); @@ -232,12 +232,7 @@ function translateTypeAnnotation( ); } case 'UnionTypeAnnotation': { - return emitUnionTypeAnnotation( - nullable, - hasteModuleName, - typeAnnotation, - parser, - ); + return emitUnion(nullable, hasteModuleName, typeAnnotation, parser); } case 'StringLiteralTypeAnnotation': { // 'a' is a special case for 'a' | 'b' but the type name is different @@ -248,7 +243,7 @@ function translateTypeAnnotation( } case 'MixedTypeAnnotation': { if (cxxOnly) { - return emitMixedTypeAnnotation(nullable); + return emitMixed(nullable); } // Fallthrough } diff --git a/packages/react-native-codegen/src/parsers/parsers-commons.js b/packages/react-native-codegen/src/parsers/parsers-commons.js index b62c1029fc7..a7884085f91 100644 --- a/packages/react-native-codegen/src/parsers/parsers-commons.js +++ b/packages/react-native-codegen/src/parsers/parsers-commons.js @@ -21,7 +21,6 @@ import type { NativeModuleFunctionTypeAnnotation, NativeModuleParamTypeAnnotation, NativeModulePropertyShape, - NativeModuleUnionTypeAnnotation, SchemaType, } from '../CodegenSchema.js'; @@ -42,7 +41,6 @@ const { UnsupportedEnumDeclarationParserError, UnsupportedGenericParserError, UnsupportedObjectPropertyTypeAnnotationParserError, - UnsupportedUnionTypeAnnotationParserError, UnnamedFunctionParamParserError, } = require('./errors'); @@ -207,32 +205,6 @@ function parseObjectProperty( }; } -function emitUnionTypeAnnotation( - nullable: boolean, - hasteModuleName: string, - typeAnnotation: $FlowFixMe, - parser: Parser, -): Nullable { - const unionTypes = parser.remapUnionTypeAnnotationMemberNames( - typeAnnotation.types, - ); - - // Only support unionTypes of the same kind - if (unionTypes.length > 1) { - throw new UnsupportedUnionTypeAnnotationParserError( - hasteModuleName, - typeAnnotation, - unionTypes, - parser.language(), - ); - } - - return wrapNullable(nullable, { - type: 'UnionTypeAnnotation', - memberType: unionTypes[0], - }); -} - function translateDefault( hasteModuleName: string, typeAnnotation: $FlowFixMe, @@ -469,7 +441,6 @@ module.exports = { assertGenericTypeAnnotationHasExactlyOneTypeParameter, isObjectProperty, parseObjectProperty, - emitUnionTypeAnnotation, translateDefault, translateFunctionTypeAnnotation, buildPropertySchema, diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 3e482cdf624..1f2ce738a6f 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -25,6 +25,7 @@ import type { NativeModuleNumberTypeAnnotation, NativeModulePromiseTypeAnnotation, NativeModuleTypeAliasTypeAnnotation, + NativeModuleUnionTypeAnnotation, ObjectTypeAnnotation, ReservedTypeAnnotation, StringTypeAnnotation, @@ -38,6 +39,7 @@ import type { TypeDeclarationMap, } from './utils'; +const {UnsupportedUnionTypeAnnotationParserError} = require('./errors'); const { throwIfArrayElementTypeAnnotationIsUnsupported, } = require('./error-utils'); @@ -119,7 +121,7 @@ function emitFunction( return wrapNullable(nullable, translateFunctionTypeAnnotationValue); } -function emitMixedTypeAnnotation( +function emitMixed( nullable: boolean, ): Nullable { return wrapNullable(nullable, { @@ -249,6 +251,32 @@ function emitFloat( }); } +function emitUnion( + nullable: boolean, + hasteModuleName: string, + typeAnnotation: $FlowFixMe, + parser: Parser, +): Nullable { + const unionTypes = parser.remapUnionTypeAnnotationMemberNames( + typeAnnotation.types, + ); + + // Only support unionTypes of the same kind + if (unionTypes.length > 1) { + throw new UnsupportedUnionTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + unionTypes, + parser.language(), + ); + } + + return wrapNullable(nullable, { + type: 'UnionTypeAnnotation', + memberType: unionTypes[0], + }); +} + function translateArrayTypeAnnotation( hasteModuleName: string, types: TypeDeclarationMap, @@ -318,7 +346,8 @@ module.exports = { emitVoid, emitString, emitStringish, - emitMixedTypeAnnotation, + emitMixed, + emitUnion, typeAliasResolution, translateArrayTypeAnnotation, }; diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/index.js b/packages/react-native-codegen/src/parsers/typescript/modules/index.js index 7157a09e32a..5c829b03e8a 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -28,7 +28,6 @@ const {resolveTypeAnnotation, getTypes} = require('../utils.js'); const { assertGenericTypeAnnotationHasExactlyOneTypeParameter, parseObjectProperty, - emitUnionTypeAnnotation, translateDefault, buildPropertySchema, } = require('../../parsers-commons'); @@ -46,7 +45,8 @@ const { emitVoid, emitString, emitStringish, - emitMixedTypeAnnotation, + emitMixed, + emitUnion, typeAliasResolution, translateArrayTypeAnnotation, } = require('../../parsers-primitives'); @@ -248,16 +248,11 @@ function translateTypeAnnotation( ); } case 'TSUnionType': { - return emitUnionTypeAnnotation( - nullable, - hasteModuleName, - typeAnnotation, - parser, - ); + return emitUnion(nullable, hasteModuleName, typeAnnotation, parser); } case 'TSUnknownKeyword': { if (cxxOnly) { - return emitMixedTypeAnnotation(nullable); + return emitMixed(nullable); } // Fallthrough }