Add support for StringLiteralTypeAnnotation (#46827)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46827

You can now define a native module that takes an argument that is a specific string literal:

Like this:
```
export interface Spec extends TurboModule {
  +passString: (arg: string) => void;
  +passStringLiteral: (arg: 'A String Literal') => void;
}
```

On the native side, this will still generate `string`, but the schema will now store the string literal, and it will be allowed in JS. This should allow more strict flow / typescript types for modules.

This will also allow the compatibility check to fail if the literal changes.

This is a step towards accepting a union of string literals.

Changelog: [General][Added] Codegen for Native Modules now supports string literals

Reviewed By: GijsWeterings

Differential Revision: D63872440

fbshipit-source-id: e54b97d34af4a3d1af51727db0777f26fb7b778c
This commit is contained in:
Eli White
2024-10-07 12:35:19 -07:00
committed by Facebook GitHub Bot
parent 73ce1984e8
commit d2f3f06826
26 changed files with 593 additions and 7 deletions
@@ -22,6 +22,7 @@ import type {
NativeModuleNumberTypeAnnotation,
NativeModuleObjectTypeAnnotation,
StringTypeAnnotation,
StringLiteralTypeAnnotation,
NativeModuleTypeAliasTypeAnnotation,
Nullable,
ReservedTypeAnnotation,
@@ -58,6 +59,7 @@ export type StructProperty = $ReadOnly<{
export type StructTypeAnnotation =
| StringTypeAnnotation
| StringLiteralTypeAnnotation
| NativeModuleNumberTypeAnnotation
| Int32TypeAnnotation
| DoubleTypeAnnotation
@@ -94,6 +94,8 @@ function toObjCType(
}
case 'StringTypeAnnotation':
return 'NSString *';
case 'StringLiteralTypeAnnotation':
return 'NSString *';
case 'NumberTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'FloatTypeAnnotation':
@@ -173,6 +175,8 @@ function toObjCValue(
}
case 'StringTypeAnnotation':
return value;
case 'StringLiteralTypeAnnotation':
return value;
case 'NumberTypeAnnotation':
return wrapPrimitive('double');
case 'FloatTypeAnnotation':
@@ -85,6 +85,8 @@ function toObjCType(
}
case 'StringTypeAnnotation':
return 'NSString *';
case 'StringLiteralTypeAnnotation':
return 'NSString *';
case 'NumberTypeAnnotation':
return wrapCxxOptional('double', isRequired);
case 'FloatTypeAnnotation':
@@ -163,6 +165,8 @@ function toObjCValue(
}
case 'StringTypeAnnotation':
return RCTBridgingTo('String');
case 'StringLiteralTypeAnnotation':
return RCTBridgingTo('String');
case 'NumberTypeAnnotation':
return RCTBridgingTo('Double');
case 'FloatTypeAnnotation':
@@ -15,9 +15,13 @@ const {toPascalCase} = require('../../Utils');
function getEventEmitterTypeObjCType(
eventEmitter: NativeModuleEventEmitterShape,
): string {
switch (eventEmitter.typeAnnotation.typeAnnotation.type) {
const type = eventEmitter.typeAnnotation.typeAnnotation.type;
switch (type) {
case 'StringTypeAnnotation':
return 'NSString *_Nonnull';
case 'StringLiteralTypeAnnotation':
return 'NSString *_Nonnull';
case 'NumberTypeAnnotation':
return 'NSNumber *_Nonnull';
case 'BooleanTypeAnnotation':
@@ -28,7 +32,16 @@ function getEventEmitterTypeObjCType(
return 'NSDictionary *';
case 'ArrayTypeAnnotation':
return 'NSArray<id<NSObject>> *';
case 'DoubleTypeAnnotation':
case 'FloatTypeAnnotation':
case 'Int32TypeAnnotation':
case 'VoidTypeAnnotation':
// TODO: Add support for these types
throw new Error(
`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
);
default:
(type: empty);
throw new Error(
`Unsupported eventType for ${eventEmitter.name}. Found: ${eventEmitter.typeAnnotation.typeAnnotation.type}`,
);
@@ -257,6 +257,8 @@ function getParamObjCType(
}
case 'StringTypeAnnotation':
return notStruct(wrapOptional('NSString *', !nullable));
case 'StringLiteralTypeAnnotation':
return notStruct(wrapOptional('NSString *', !nullable));
case 'NumberTypeAnnotation':
return notStruct(isRequired ? 'double' : 'NSNumber *');
case 'FloatTypeAnnotation':
@@ -330,6 +332,10 @@ function getReturnObjCType(
// TODO: Can NSString * returns not be _Nullable?
// In the legacy codegen, we don't surround NSSTring * with _Nullable
return wrapOptional('NSString *', isRequired);
case 'StringLiteralTypeAnnotation':
// TODO: Can NSString * returns not be _Nullable?
// In the legacy codegen, we don't surround NSSTring * with _Nullable
return wrapOptional('NSString *', isRequired);
case 'NumberTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'FloatTypeAnnotation':
@@ -396,6 +402,8 @@ function getReturnJSType(
return 'NumberKind';
case 'StringTypeAnnotation':
return 'StringKind';
case 'StringLiteralTypeAnnotation':
return 'StringKind';
case 'NumberTypeAnnotation':
return 'NumberKind';
case 'FloatTypeAnnotation':