From 4285a6b7e55536650a8f6acd75461ff41b742811 Mon Sep 17 00:00:00 2001 From: Eli White Date: Sun, 29 Sep 2024 14:09:01 -0700 Subject: [PATCH 1/3] Add a test for an Alias to an Alias Summary: This covers types that deeply alias. Differential Revision: D62926913 --- .../modules/__test_fixtures__/fixtures.js | 2 ++ .../module-parser-snapshot-test.js.snap | 20 +++++++++++++++++++ .../modules/__test_fixtures__/fixtures.js | 2 ++ ...script-module-parser-snapshot-test.js.snap | 20 +++++++++++++++++++ 4 files changed, 44 insertions(+) diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js index a555772d09ecab..9544c8999ce157 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/fixtures.js @@ -162,6 +162,7 @@ export type ObjectAlias = {| label: string, truthy: boolean, |}; +export type PureObjectAlias = ObjectAlias; export type ReadOnlyAlias = $ReadOnly; export interface Spec extends TurboModule { @@ -171,6 +172,7 @@ export interface Spec extends TurboModule { +getArray: (a: Array) => {| a: B |}; +getStringFromAlias: (a: ObjectAlias) => string; +getStringFromNullableAlias: (a: ?ObjectAlias) => string; + +getStringFromPureAlias: (a: PureObjectAlias) => string; +getStringFromReadOnlyAlias: (a: ReadOnlyAlias) => string; +getStringFromNullableReadOnlyAlias: (a: ?ReadOnlyAlias) => string; } diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 83e6f63fbd9e2a..9594001afb615b 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -688,6 +688,26 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_ALIASES ] } }, + { + 'name': 'getStringFromPureAlias', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'StringTypeAnnotation' + }, + 'params': [ + { + 'name': 'a', + 'optional': false, + 'typeAnnotation': { + 'type': 'TypeAliasTypeAnnotation', + 'name': 'ObjectAlias' + } + } + ] + } + }, { 'name': 'getStringFromReadOnlyAlias', 'optional': false, diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js index 7ebbe9846ad25a..41495d6dc54162 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/fixtures.js @@ -146,6 +146,7 @@ export type ObjectAlias = { label: string; truthy: boolean; }; +export type PureObjectAlias = ObjectAlias; export type ReadOnlyAlias = Readonly; export interface Spec extends TurboModule { @@ -155,6 +156,7 @@ export interface Spec extends TurboModule { readonly getArray: (a: Array) => {a: B}; readonly getStringFromAlias: (a: ObjectAlias) => string; readonly getStringFromNullableAlias: (a: ObjectAlias | null) => string; + readonly getStringFromPureAlias: (a: PureObjectAlias) => string; readonly getStringFromReadOnlyAlias: (a: ReadOnlyAlias) => string; readonly getStringFromNullableReadOnlyAlias: (a: ReadOnlyAlias | null) => string; } diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap index 02351a5ba78b1a..22bea569c7068b 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap @@ -679,6 +679,26 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_AL ] } }, + { + 'name': 'getStringFromPureAlias', + 'optional': false, + 'typeAnnotation': { + 'type': 'FunctionTypeAnnotation', + 'returnTypeAnnotation': { + 'type': 'StringTypeAnnotation' + }, + 'params': [ + { + 'name': 'a', + 'optional': false, + 'typeAnnotation': { + 'type': 'TypeAliasTypeAnnotation', + 'name': 'ObjectAlias' + } + } + ] + } + }, { 'name': 'getStringFromReadOnlyAlias', 'optional': false, From e558987da7292816719128765e2d5559533d9045 Mon Sep 17 00:00:00 2001 From: Eli White Date: Sun, 29 Sep 2024 14:22:48 -0700 Subject: [PATCH 2/3] Add test for Object with indexers Summary: An object isn't allowed to have both an indexer and regular properties. Previously, the schema just wouldn't include the properties and would only include the indexer. Instead of failing silently and not generating the expected code, let's explicitly error out. Differential Revision: D63615090 --- .../src/parsers/errors.js | 10 +++++++ .../modules/__test_fixtures__/failures.js | 29 +++++++++++++++++++ .../module-parser-snapshot-test.js.snap | 2 ++ .../src/parsers/flow/modules/index.js | 9 ++++++ .../modules/__test_fixtures__/failures.js | 26 +++++++++++++++++ ...script-module-parser-snapshot-test.js.snap | 2 ++ .../src/parsers/typescript/modules/index.js | 13 +++++++++ 7 files changed, 91 insertions(+) diff --git a/packages/react-native-codegen/src/parsers/errors.js b/packages/react-native-codegen/src/parsers/errors.js index 91b9c827b24575..5fa37f58afba55 100644 --- a/packages/react-native-codegen/src/parsers/errors.js +++ b/packages/react-native-codegen/src/parsers/errors.js @@ -237,6 +237,15 @@ class UnsupportedObjectPropertyTypeAnnotationParserError extends ParserError { } } +class UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError extends ParserError { + constructor(nativeModuleName: string, propertyAST: $FlowFixMe) { + let message = + "'ObjectTypeAnnotation' cannot contain both an indexer and properties."; + + super(nativeModuleName, propertyAST, message); + } +} + class UnsupportedObjectPropertyValueTypeAnnotationParserError extends ParserError { constructor( nativeModuleName: string, @@ -455,6 +464,7 @@ module.exports = { UnsupportedModuleEventEmitterPropertyParserError, UnsupportedModulePropertyParserError, UnsupportedObjectPropertyTypeAnnotationParserError, + UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError, UnsupportedObjectPropertyValueTypeAnnotationParserError, UnsupportedObjectDirectRecursivePropertyParserError, UnusedModuleInterfaceParserError, diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/failures.js b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/failures.js index 8734095f43f2d4..91f86dbb7cafd4 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/failures.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/__test_fixtures__/failures.js @@ -265,6 +265,34 @@ export interface Spec extends TurboModule { export default TurboModuleRegistry.getEnforcing('MixedValuesEnumNativeModule'); `; +const MAP_WITH_EXTRA_KEYS_NATIVE_MODULE = ` +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from '../RCTExport'; +import * as TurboModuleRegistry from '../TurboModuleRegistry'; + +type MapWithKey = { + [a: string]: ?string, + extra: string, +} + +export interface Spec extends TurboModule { + +getMap: (a: MapWithKey) => string; +} + +export default TurboModuleRegistry.getEnforcing('MixedValuesEnumNativeModule'); +`; + module.exports = { NATIVE_MODULES_WITH_READ_ONLY_OBJECT_NO_TYPE_FOR_CONTENT, NATIVE_MODULES_WITH_UNNAMED_PARAMS, @@ -276,4 +304,5 @@ module.exports = { TWO_NATIVE_EXTENDING_TURBO_MODULE, EMPTY_ENUM_NATIVE_MODULE, MIXED_VALUES_ENUM_NATIVE_MODULE, + MAP_WITH_EXTRA_KEYS_NATIVE_MODULE, }; diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 9594001afb615b..0db49028da81f6 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -2,6 +2,8 @@ exports[`RN Codegen Flow Parser Fails with error message EMPTY_ENUM_NATIVE_MODULE 1`] = `"Module NativeSampleTurboModule: Failed parsing the enum SomeEnum in NativeSampleTurboModule with the error: Enums should have at least one member and member values can not be mixed- they all must be either blank, number, or string values."`; +exports[`RN Codegen Flow Parser Fails with error message MAP_WITH_EXTRA_KEYS_NATIVE_MODULE 1`] = `"Module NativeSampleTurboModule: 'ObjectTypeAnnotation' cannot contain both an indexer and properties."`; + exports[`RN Codegen Flow Parser Fails with error message MIXED_VALUES_ENUM_NATIVE_MODULE 1`] = ` "Syntax error in path/NativeSampleTurboModule.js: cannot use string initializer in number enum (19:2) STR = 'str', 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 adfea71f5b1f09..1fb9a52adb2a20 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/index.js +++ b/packages/react-native-codegen/src/parsers/flow/modules/index.js @@ -24,6 +24,7 @@ import type {ParserErrorCapturer, TypeDeclarationMap} from '../../utils'; const { UnsupportedEnumDeclarationParserError, UnsupportedGenericParserError, + UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError, UnsupportedTypeAnnotationParserError, } = require('../../errors'); const { @@ -162,6 +163,14 @@ function translateTypeAnnotation( const indexers = typeAnnotation.indexers.filter( member => member.type === 'ObjectTypeIndexer', ); + + if (indexers.length > 0 && typeAnnotation.properties.length > 0) { + throw new UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + ); + } + if (indexers.length > 0) { // check the property type to prevent developers from using unsupported types // the return value from `translateTypeAnnotation` is unused diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/failures.js b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/failures.js index a8d08e8395ff9a..e7a78e65b0e172 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/failures.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__test_fixtures__/failures.js @@ -208,6 +208,31 @@ export default TurboModuleRegistry.getEnforcing( ); `; +const MAP_WITH_EXTRA_KEYS_NATIVE_MODULE = ` +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport'; +import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry'; + +type MapWithKey = { + [a: string]: string | null, + extra: string, +} + +export interface Spec extends TurboModule { + readonly getMap: (a: MapWithKey) => string; +} + +export default TurboModuleRegistry.getEnforcing('MapWithExtraKeysNativeModule'); +`; + module.exports = { NATIVE_MODULES_WITH_UNNAMED_PARAMS, NATIVE_MODULES_WITH_PROMISE_WITHOUT_TYPE, @@ -218,4 +243,5 @@ module.exports = { TWO_NATIVE_EXTENDING_TURBO_MODULE, EMPTY_ENUM_NATIVE_MODULE, MIXED_VALUES_ENUM_NATIVE_MODULE, + MAP_WITH_EXTRA_KEYS_NATIVE_MODULE, }; diff --git a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap index 22bea569c7068b..8e99438fd9efdf 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap @@ -2,6 +2,8 @@ exports[`RN Codegen TypeScript Parser Fails with error message EMPTY_ENUM_NATIVE_MODULE 1`] = `"Module NativeSampleTurboModule: Failed parsing the enum SomeEnum in NativeSampleTurboModule with the error: Enums should have at least one member."`; +exports[`RN Codegen TypeScript Parser Fails with error message MAP_WITH_EXTRA_KEYS_NATIVE_MODULE 1`] = `"Module NativeSampleTurboModule: 'ObjectTypeAnnotation' cannot contain both an indexer and properties."`; + exports[`RN Codegen TypeScript Parser Fails with error message MIXED_VALUES_ENUM_NATIVE_MODULE 1`] = `"Module NativeSampleTurboModule: Failed parsing the enum SomeEnum in NativeSampleTurboModule with the error: Enum values can not be mixed. They all must be either blank, number, or string values."`; exports[`RN Codegen TypeScript Parser Fails with error message NATIVE_MODULES_WITH_ARRAY_WITH_NO_TYPE_FOR_CONTENT 1`] = `"Module NativeSampleTurboModule: Generic 'Array' must have type parameters."`; 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 ef87bd26ce309c..db696d0b7b4762 100644 --- a/packages/react-native-codegen/src/parsers/typescript/modules/index.js +++ b/packages/react-native-codegen/src/parsers/typescript/modules/index.js @@ -28,6 +28,7 @@ import type { const { UnsupportedEnumDeclarationParserError, UnsupportedGenericParserError, + UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError, UnsupportedTypeAnnotationParserError, } = require('../../errors'); const {parseObjectProperty} = require('../../parsers-commons'); @@ -308,6 +309,18 @@ function translateTypeAnnotation( const indexSignatures = typeAnnotation.members.filter( member => member.type === 'TSIndexSignature', ); + + const properties = typeAnnotation.members.filter( + member => member.type === 'TSPropertySignature', + ); + + if (indexSignatures.length > 0 && properties.length > 0) { + throw new UnsupportedObjectPropertyWithIndexerTypeAnnotationParserError( + hasteModuleName, + typeAnnotation, + ); + } + if (indexSignatures.length > 0) { // check the property type to prevent developers from using unsupported types // the return value from `translateTypeAnnotation` is unused From a74e00a42bd2204bfdf2952b5a506e02303d92fc Mon Sep 17 00:00:00 2001 From: Eli White Date: Sun, 29 Sep 2024 17:19:38 -0700 Subject: [PATCH 3/3] Promise annotations must specify their elementType Summary: It makes scripts operating on the schema complicated when the elementType might be there or might not. Let's make it required, but VoidTypeAnnotation if it's unknown. Arguably we shouldn't allow it to be unknown at all, but that's out of scope here. Differential Revision: D63616703 --- .../react-native-codegen/src/CodegenSchema.d.ts | 2 +- .../react-native-codegen/src/CodegenSchema.js | 2 +- .../src/generators/__test_fixtures__/fixtures.js | 3 +++ .../modules/__test_fixtures__/fixtures.js | 15 +++++++++++++++ .../module-parser-snapshot-test.js.snap | 15 ++++++++++++--- .../src/parsers/parsers-primitives.js | 6 ++++++ 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/packages/react-native-codegen/src/CodegenSchema.d.ts b/packages/react-native-codegen/src/CodegenSchema.d.ts index 0a99ea06e16521..f3b1c2ae6d086a 100644 --- a/packages/react-native-codegen/src/CodegenSchema.d.ts +++ b/packages/react-native-codegen/src/CodegenSchema.d.ts @@ -347,7 +347,7 @@ export interface NativeModuleTypeAliasTypeAnnotation { export interface NativeModulePromiseTypeAnnotation { readonly type: 'PromiseTypeAnnotation'; - readonly elementType?: Nullable | undefined; + readonly elementType: Nullable | VoidTypeAnnotation; } export type UnionTypeAnnotationMemberType = diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index a8eecac05d7d8f..87e92425165f4f 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -333,7 +333,7 @@ export type NativeModuleTypeAliasTypeAnnotation = $ReadOnly<{ export type NativeModulePromiseTypeAnnotation = $ReadOnly<{ type: 'PromiseTypeAnnotation', - elementType?: Nullable, + elementType: VoidTypeAnnotation | Nullable, }>; export type UnionTypeAnnotationMemberType = diff --git a/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js index d0ddfeaff730d5..b3d5788df030de 100644 --- a/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/__test_fixtures__/fixtures.js @@ -53,6 +53,9 @@ const SCHEMA_WITH_TM_AND_FC: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index f7a65fe0a5621e..ac9cf2189c74e1 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -453,6 +453,9 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { @@ -472,6 +475,9 @@ const SIMPLE_NATIVE_MODULES: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { @@ -1365,6 +1371,9 @@ const REAL_MODULE_EXAMPLE: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { @@ -1385,6 +1394,9 @@ const REAL_MODULE_EXAMPLE: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { @@ -1411,6 +1423,9 @@ const REAL_MODULE_EXAMPLE: SchemaType = { type: 'FunctionTypeAnnotation', returnTypeAnnotation: { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }, params: [ { diff --git a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap index 0db49028da81f6..be6a7997ced9d6 100644 --- a/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap @@ -2406,7 +2406,10 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'VoidTypeAnnotation' + } }, 'params': [] } @@ -2417,7 +2420,10 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'VoidTypeAnnotation' + } }, 'params': [] } @@ -2428,7 +2434,10 @@ exports[`RN Codegen Flow Parser can generate fixture PROMISE_WITH_COMMONLY_USED_ 'typeAnnotation': { 'type': 'FunctionTypeAnnotation', 'returnTypeAnnotation': { - 'type': 'PromiseTypeAnnotation' + 'type': 'PromiseTypeAnnotation', + 'elementType': { + 'type': 'VoidTypeAnnotation' + } }, 'params': [] } diff --git a/packages/react-native-codegen/src/parsers/parsers-primitives.js b/packages/react-native-codegen/src/parsers/parsers-primitives.js index 5fead2c4acf47a..cb16608bbb3ce9 100644 --- a/packages/react-native-codegen/src/parsers/parsers-primitives.js +++ b/packages/react-native-codegen/src/parsers/parsers-primitives.js @@ -316,6 +316,9 @@ function emitPromise( ) { return wrapNullable(nullable, { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }); } else { try { @@ -335,6 +338,9 @@ function emitPromise( } catch { return wrapNullable(nullable, { type: 'PromiseTypeAnnotation', + elementType: { + type: 'VoidTypeAnnotation', + }, }); } }