mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
simple support to the Partial<T> annotation (#35961)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/35961 Pull Request resolved: https://github.com/facebook/react-native/pull/35960 This fixes #35864 This feature allows using `$Partial<Obj>` in flow and `Partial<Obj>` in TypeScript based on the spec mentioned here: https://flow.org/en/docs/types/utilities/#toc-partial. We currently only allow passing an Obj to Partial so ``` export type SomeObj = { a: string, b?: boolean, }; export type PartialSomeObj = Partial<SomeObj>; ``` should work. and also- ``` export type PartialSomeObj = Partial<{ a: string, b?: boolean, }>; ``` But not ``` export type PartialSomeObj = Partial<Partial<{ a: string, b?: boolean, }>>; ``` This can be improved in the future by a recursive unwrapping of the value inside the `Partial` annotation. Changelog: [General] [Added] - Allow the use of "Partial<T>" in Turbo Module specs. Reviewed By: christophpurrer, cipolleschi Differential Revision: D42640880 fbshipit-source-id: 03a3fccc38ccfc7a5440fe11893beb68e77753f3
This commit is contained in:
committed by
Facebook GitHub Bot
parent
53932d0022
commit
97e707d897
Vendored
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 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 'react-native/Libraries/TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';
|
||||
|
||||
export type SomeObj = {|
|
||||
a: string,
|
||||
b?: boolean,
|
||||
|};
|
||||
|
||||
export type PartialSomeObj = $Partial<SomeObj>;
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getSomeObj: () => SomeObj;
|
||||
+getPartialSomeObj: () => $Partial<SomeObj>;
|
||||
+getSomeObjFromPartialSomeObj: (value: $Partial<SomeObj>) => SomeObj;
|
||||
+getPartialPartial: (
|
||||
value1: $Partial<SomeObj>,
|
||||
value2: PartialSomeObj,
|
||||
) => SomeObj;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.getEnforcing<Spec>(
|
||||
'NativePartialAnnotationTurboModule',
|
||||
): Spec);
|
||||
+251
@@ -430,6 +430,74 @@ namespace facebook {
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetSomeObjFromPartialSomeObjValue {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetSomeObjFromPartialSomeObjValue(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue:(id)json;
|
||||
@end
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetPartialPartialValue1 {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetPartialPartialValue1(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1:(id)json;
|
||||
@end
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetPartialPartialValue2 {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetPartialPartialValue2(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2:(id)json;
|
||||
@end
|
||||
@protocol NativePartialAnnotationTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (NSDictionary *)getSomeObj;
|
||||
- (NSDictionary *)getPartialSomeObj;
|
||||
- (NSDictionary *)getSomeObjFromPartialSomeObj:(JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue &)value;
|
||||
- (NSDictionary *)getPartialPartial:(JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1 &)value1
|
||||
value2:(JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2 &)value2;
|
||||
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'NativePartialAnnotationTurboModule'
|
||||
*/
|
||||
class JSI_EXPORT NativePartialAnnotationTurboModuleSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativePartialAnnotationTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@protocol NativePromiseTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
@@ -1069,6 +1137,36 @@ inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(const In
|
||||
inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{
|
||||
return i.unsafeRawValue();
|
||||
}) {}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
|
||||
inline double JS::NativeSampleTurboModule::SpecGetObjectShapeArg::prop() const
|
||||
{
|
||||
@@ -1622,6 +1720,74 @@ namespace facebook {
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetSomeObjFromPartialSomeObjValue {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetSomeObjFromPartialSomeObjValue(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue:(id)json;
|
||||
@end
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetPartialPartialValue1 {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetPartialPartialValue1(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1:(id)json;
|
||||
@end
|
||||
namespace JS {
|
||||
namespace NativePartialAnnotationTurboModule {
|
||||
struct SpecGetPartialPartialValue2 {
|
||||
NSString *a() const;
|
||||
std::optional<bool> b() const;
|
||||
|
||||
SpecGetPartialPartialValue2(NSDictionary *const v) : _v(v) {}
|
||||
private:
|
||||
NSDictionary *_v;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@interface RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2:(id)json;
|
||||
@end
|
||||
@protocol NativePartialAnnotationTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
- (NSDictionary *)getSomeObj;
|
||||
- (NSDictionary *)getPartialSomeObj;
|
||||
- (NSDictionary *)getSomeObjFromPartialSomeObj:(JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue &)value;
|
||||
- (NSDictionary *)getPartialPartial:(JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1 &)value1
|
||||
value2:(JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2 &)value2;
|
||||
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
/**
|
||||
* ObjC++ class for module 'NativePartialAnnotationTurboModule'
|
||||
*/
|
||||
class JSI_EXPORT NativePartialAnnotationTurboModuleSpecJSI : public ObjCTurboModule {
|
||||
public:
|
||||
NativePartialAnnotationTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms);
|
||||
};
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
@protocol NativePromiseTurboModuleSpec <RCTBridgeModule, RCTTurboModule>
|
||||
|
||||
@@ -2261,6 +2427,36 @@ inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(const In
|
||||
inline JS::NativeOptionalObjectTurboModule::Constants::Builder::Builder(Constants i) : _factory(^{
|
||||
return i.unsafeRawValue();
|
||||
}) {}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
inline NSString *JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2::a() const
|
||||
{
|
||||
id const p = _v[@\\"a\\"];
|
||||
return RCTBridgingToOptionalString(p);
|
||||
}
|
||||
inline std::optional<bool> JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2::b() const
|
||||
{
|
||||
id const p = _v[@\\"b\\"];
|
||||
return RCTBridgingToOptionalBool(p);
|
||||
}
|
||||
|
||||
inline double JS::NativeSampleTurboModule::SpecGetObjectShapeArg::prop() const
|
||||
{
|
||||
@@ -2620,6 +2816,61 @@ namespace facebook {
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@implementation RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue:(id)json
|
||||
{
|
||||
return facebook::react::managedPointer<JS::NativePartialAnnotationTurboModule::SpecGetSomeObjFromPartialSomeObjValue>(json);
|
||||
}
|
||||
@end
|
||||
@implementation RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1:(id)json
|
||||
{
|
||||
return facebook::react::managedPointer<JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue1>(json);
|
||||
}
|
||||
@end
|
||||
@implementation RCTCxxConvert (NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2)
|
||||
+ (RCTManagedPointer *)JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2:(id)json
|
||||
{
|
||||
return facebook::react::managedPointer<JS::NativePartialAnnotationTurboModule::SpecGetPartialPartialValue2>(json);
|
||||
}
|
||||
@end
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getSomeObj(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getSomeObj\\", @selector(getSomeObj), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getPartialSomeObj(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getPartialSomeObj\\", @selector(getPartialSomeObj), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getSomeObjFromPartialSomeObj(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getSomeObjFromPartialSomeObj\\", @selector(getSomeObjFromPartialSomeObj:), args, count);
|
||||
}
|
||||
|
||||
static facebook::jsi::Value __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getPartialPartial(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
||||
return static_cast<ObjCTurboModule&>(turboModule).invokeObjCMethod(rt, ObjectKind, \\"getPartialPartial\\", @selector(getPartialPartial:value2:), args, count);
|
||||
}
|
||||
|
||||
NativePartialAnnotationTurboModuleSpecJSI::NativePartialAnnotationTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms)
|
||||
: ObjCTurboModule(params) {
|
||||
|
||||
methodMap_[\\"getSomeObj\\"] = MethodMetadata {0, __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getSomeObj};
|
||||
|
||||
|
||||
methodMap_[\\"getPartialSomeObj\\"] = MethodMetadata {0, __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getPartialSomeObj};
|
||||
|
||||
|
||||
methodMap_[\\"getSomeObjFromPartialSomeObj\\"] = MethodMetadata {1, __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getSomeObjFromPartialSomeObj};
|
||||
setMethodArgConversionSelector(@\\"getSomeObjFromPartialSomeObj\\", 0, @\\"JS_NativePartialAnnotationTurboModule_SpecGetSomeObjFromPartialSomeObjValue:\\");
|
||||
|
||||
methodMap_[\\"getPartialPartial\\"] = MethodMetadata {2, __hostFunction_NativePartialAnnotationTurboModuleSpecJSI_getPartialPartial};
|
||||
setMethodArgConversionSelector(@\\"getPartialPartial\\", 0, @\\"JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue1:\\");
|
||||
setMethodArgConversionSelector(@\\"getPartialPartial\\", 1, @\\"JS_NativePartialAnnotationTurboModule_SpecGetPartialPartialValue2:\\");
|
||||
}
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
+83
-18
@@ -21,6 +21,7 @@ const {
|
||||
emitNumber,
|
||||
emitInt32,
|
||||
emitObject,
|
||||
emitPartial,
|
||||
emitPromise,
|
||||
emitRootTag,
|
||||
emitVoid,
|
||||
@@ -454,30 +455,94 @@ describe('emitObject', () => {
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('emitFloat', () => {
|
||||
describe('when nullable is true', () => {
|
||||
it('returns nullable type annotation', () => {
|
||||
const result = emitFloat(true);
|
||||
const expected = {
|
||||
type: 'NullableTypeAnnotation',
|
||||
describe('emitPartial', () => {
|
||||
describe('when nullable is true', () => {
|
||||
it('returns nullable type annotation', () => {
|
||||
const props = [
|
||||
{
|
||||
name: 'a',
|
||||
optional: true,
|
||||
typeAnnotation: {
|
||||
type: 'FloatTypeAnnotation',
|
||||
type: 'StringTypeAnnotation',
|
||||
},
|
||||
};
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
optional: true,
|
||||
typeAnnotation: {
|
||||
type: 'BooleanTypeAnnotation',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
const result = emitPartial(true, props);
|
||||
|
||||
const expected = {
|
||||
type: 'NullableTypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
properties: props,
|
||||
},
|
||||
};
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
describe('when nullable is false', () => {
|
||||
it('returns non nullable type annotation', () => {
|
||||
const result = emitFloat(false);
|
||||
const expected = {
|
||||
type: 'FloatTypeAnnotation',
|
||||
};
|
||||
});
|
||||
describe('when nullable is false', () => {
|
||||
it('returns non nullable type annotation', () => {
|
||||
const props = [
|
||||
{
|
||||
name: 'a',
|
||||
optional: true,
|
||||
typeAnnotation: {
|
||||
type: 'StringTypeAnnotation',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'b',
|
||||
optional: true,
|
||||
typeAnnotation: {
|
||||
type: 'BooleanTypeAnnotation',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
const result = emitPartial(false, props);
|
||||
|
||||
const expected = {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
properties: props,
|
||||
};
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('emitFloat', () => {
|
||||
describe('when nullable is true', () => {
|
||||
it('returns nullable type annotation', () => {
|
||||
const result = emitFloat(true);
|
||||
const expected = {
|
||||
type: 'NullableTypeAnnotation',
|
||||
typeAnnotation: {
|
||||
type: 'FloatTypeAnnotation',
|
||||
},
|
||||
};
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
describe('when nullable is false', () => {
|
||||
it('returns non nullable type annotation', () => {
|
||||
const result = emitFloat(false);
|
||||
const expected = {
|
||||
type: 'FloatTypeAnnotation',
|
||||
};
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+64
@@ -288,6 +288,68 @@ export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_PARTIALS = `
|
||||
/**
|
||||
* 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';
|
||||
|
||||
export type SomeObj = {|
|
||||
a: string,
|
||||
b?: boolean,
|
||||
|};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getSomeObj: () => SomeObj;
|
||||
+getPartialSomeObj: () => $Partial<SomeObj>;
|
||||
+getSomeObjFromPartialSomeObj: (value: $Partial<SomeObj>) => SomeObj;
|
||||
}
|
||||
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_PARTIALS_COMPLEX = `
|
||||
/**
|
||||
* 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';
|
||||
|
||||
export type SomeObj = {|
|
||||
a: string,
|
||||
b?: boolean,
|
||||
|};
|
||||
|
||||
export type PartialSomeObj = $Partial<SomeObj>;
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getPartialPartial: (value1: $Partial<SomeObj>, value2: PartialSomeObj) => SomeObj
|
||||
}
|
||||
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_ROOT_TAG = `
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
@@ -732,6 +794,8 @@ module.exports = {
|
||||
NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY,
|
||||
NATIVE_MODULE_WITH_SIMPLE_OBJECT,
|
||||
NATIVE_MODULE_WITH_UNSAFE_OBJECT,
|
||||
NATIVE_MODULE_WITH_PARTIALS,
|
||||
NATIVE_MODULE_WITH_PARTIALS_COMPLEX,
|
||||
NATIVE_MODULE_WITH_ROOT_TAG,
|
||||
NATIVE_MODULE_WITH_NULLABLE_PARAM,
|
||||
NATIVE_MODULE_WITH_BASIC_ARRAY,
|
||||
|
||||
+206
@@ -1431,6 +1431,212 @@ exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_OBJECT_W
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PARTIALS 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
'NativeSampleTurboModule': {
|
||||
'type': 'NativeModule',
|
||||
'aliases': {
|
||||
'SomeObj': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'spec': {
|
||||
'properties': [
|
||||
{
|
||||
'name': 'getSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': []
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'getPartialSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'params': []
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'getSomeObjFromPartialSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': [
|
||||
{
|
||||
'name': 'value',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'moduleName': 'SampleTurboModule'
|
||||
}
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PARTIALS_COMPLEX 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
'NativeSampleTurboModule': {
|
||||
'type': 'NativeModule',
|
||||
'aliases': {
|
||||
'SomeObj': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'spec': {
|
||||
'properties': [
|
||||
{
|
||||
'name': 'getPartialPartial',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': [
|
||||
{
|
||||
'name': 'value1',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'value2',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'moduleName': 'SampleTurboModule'
|
||||
}
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen Flow Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
|
||||
@@ -42,6 +42,7 @@ const {
|
||||
emitNumber,
|
||||
emitInt32,
|
||||
emitObject,
|
||||
emitPartial,
|
||||
emitPromise,
|
||||
emitRootTag,
|
||||
emitVoid,
|
||||
@@ -155,6 +156,40 @@ function translateTypeAnnotation(
|
||||
case 'Object': {
|
||||
return emitObject(nullable);
|
||||
}
|
||||
case '$Partial': {
|
||||
if (typeAnnotation.typeParameters.params.length !== 1) {
|
||||
throw new Error(
|
||||
'Partials only support annotating exactly one parameter.',
|
||||
);
|
||||
}
|
||||
|
||||
const annotatedElement =
|
||||
types[typeAnnotation.typeParameters.params[0].id.name];
|
||||
|
||||
if (!annotatedElement) {
|
||||
throw new Error(
|
||||
'Partials only support annotating a type parameter.',
|
||||
);
|
||||
}
|
||||
|
||||
const properties = annotatedElement.right.properties.map(prop => {
|
||||
return {
|
||||
name: prop.key.name,
|
||||
optional: true,
|
||||
typeAnnotation: translateTypeAnnotation(
|
||||
hasteModuleName,
|
||||
prop.value,
|
||||
types,
|
||||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
parser,
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
return emitPartial(nullable, properties);
|
||||
}
|
||||
default: {
|
||||
return translateDefault(
|
||||
hasteModuleName,
|
||||
|
||||
@@ -30,6 +30,7 @@ import type {
|
||||
ReservedTypeAnnotation,
|
||||
StringTypeAnnotation,
|
||||
VoidTypeAnnotation,
|
||||
NativeModuleObjectTypeAnnotation,
|
||||
} from '../CodegenSchema';
|
||||
import type {Parser} from './parser';
|
||||
import type {
|
||||
@@ -243,6 +244,16 @@ function emitObject(
|
||||
});
|
||||
}
|
||||
|
||||
function emitPartial(
|
||||
nullable: boolean,
|
||||
properties: Array<$FlowFixMe>,
|
||||
): Nullable<NativeModuleObjectTypeAnnotation> {
|
||||
return wrapNullable(nullable, {
|
||||
type: 'ObjectTypeAnnotation',
|
||||
properties,
|
||||
});
|
||||
}
|
||||
|
||||
function emitFloat(
|
||||
nullable: boolean,
|
||||
): Nullable<NativeModuleFloatTypeAnnotation> {
|
||||
@@ -370,6 +381,7 @@ module.exports = {
|
||||
emitInt32,
|
||||
emitNumber,
|
||||
emitObject,
|
||||
emitPartial,
|
||||
emitPromise,
|
||||
emitRootTag,
|
||||
emitVoid,
|
||||
|
||||
+56
@@ -302,6 +302,60 @@ export interface Spec extends TurboModule {
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_PARTIALS = `
|
||||
/**
|
||||
* 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';
|
||||
|
||||
export type SomeObj = {
|
||||
a: string,
|
||||
b?: boolean,
|
||||
};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
getSomeObj: () => SomeObj;
|
||||
getPartialSomeObj: () => Partial<SomeObj>;
|
||||
getSomeObjFromPartialSomeObj: (value: Partial<SomeObj>) => SomeObj;
|
||||
}
|
||||
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_PARTIALS_COMPLEX = `
|
||||
/**
|
||||
* 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';
|
||||
|
||||
export type SomeObj = {
|
||||
a: string,
|
||||
b?: boolean,
|
||||
};
|
||||
|
||||
export type PartialSomeObj = Partial<SomeObj>;
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
getPartialPartial: (value1: Partial<SomeObj>, value2: PartialSomeObj) => SomeObj;
|
||||
}
|
||||
|
||||
export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
|
||||
`;
|
||||
|
||||
const NATIVE_MODULE_WITH_ROOT_TAG = `
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
@@ -754,6 +808,8 @@ module.exports = {
|
||||
NATIVE_MODULE_WITH_COMPLEX_OBJECTS_WITH_NULLABLE_KEY,
|
||||
NATIVE_MODULE_WITH_SIMPLE_OBJECT,
|
||||
NATIVE_MODULE_WITH_UNSAFE_OBJECT,
|
||||
NATIVE_MODULE_WITH_PARTIALS,
|
||||
NATIVE_MODULE_WITH_PARTIALS_COMPLEX,
|
||||
NATIVE_MODULE_WITH_ROOT_TAG,
|
||||
NATIVE_MODULE_WITH_NULLABLE_PARAM,
|
||||
NATIVE_MODULE_WITH_BASIC_ARRAY,
|
||||
|
||||
+206
@@ -1737,6 +1737,212 @@ exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_OB
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PARTIALS 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
'NativeSampleTurboModule': {
|
||||
'type': 'NativeModule',
|
||||
'aliases': {
|
||||
'SomeObj': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'spec': {
|
||||
'properties': [
|
||||
{
|
||||
'name': 'getSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': []
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'getPartialSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'params': []
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'getSomeObjFromPartialSomeObj',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': [
|
||||
{
|
||||
'name': 'value',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'moduleName': 'SampleTurboModule'
|
||||
}
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PARTIALS_COMPLEX 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
'NativeSampleTurboModule': {
|
||||
'type': 'NativeModule',
|
||||
'aliases': {
|
||||
'SomeObj': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
'spec': {
|
||||
'properties': [
|
||||
{
|
||||
'name': 'getPartialPartial',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'FunctionTypeAnnotation',
|
||||
'returnTypeAnnotation': {
|
||||
'type': 'TypeAliasTypeAnnotation',
|
||||
'name': 'SomeObj'
|
||||
},
|
||||
'params': [
|
||||
{
|
||||
'name': 'value1',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'value2',
|
||||
'optional': false,
|
||||
'typeAnnotation': {
|
||||
'type': 'ObjectTypeAnnotation',
|
||||
'properties': [
|
||||
{
|
||||
'name': 'a',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'StringTypeAnnotation'
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'b',
|
||||
'optional': true,
|
||||
'typeAnnotation': {
|
||||
'type': 'BooleanTypeAnnotation'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
'moduleName': 'SampleTurboModule'
|
||||
}
|
||||
}
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`RN Codegen TypeScript Parser can generate fixture NATIVE_MODULE_WITH_PROMISE 1`] = `
|
||||
"{
|
||||
'modules': {
|
||||
|
||||
@@ -42,6 +42,7 @@ const {
|
||||
emitNumber,
|
||||
emitInt32,
|
||||
emitObject,
|
||||
emitPartial,
|
||||
emitPromise,
|
||||
emitRootTag,
|
||||
emitVoid,
|
||||
@@ -172,6 +173,42 @@ function translateTypeAnnotation(
|
||||
case 'Object': {
|
||||
return emitObject(nullable);
|
||||
}
|
||||
case 'Partial': {
|
||||
if (typeAnnotation.typeParameters.params.length !== 1) {
|
||||
throw new Error(
|
||||
'Partials only support annotating exactly one parameter.',
|
||||
);
|
||||
}
|
||||
|
||||
const annotatedElement =
|
||||
types[typeAnnotation.typeParameters.params[0].typeName.name];
|
||||
|
||||
if (!annotatedElement) {
|
||||
throw new Error(
|
||||
'Partials only support annotating a type parameter.',
|
||||
);
|
||||
}
|
||||
|
||||
const properties = annotatedElement.typeAnnotation.members.map(
|
||||
member => {
|
||||
return {
|
||||
name: member.key.name,
|
||||
optional: true,
|
||||
typeAnnotation: translateTypeAnnotation(
|
||||
hasteModuleName,
|
||||
member.typeAnnotation.typeAnnotation,
|
||||
types,
|
||||
aliasMap,
|
||||
tryParse,
|
||||
cxxOnly,
|
||||
parser,
|
||||
),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
return emitPartial(nullable, properties);
|
||||
}
|
||||
default: {
|
||||
return translateDefault(
|
||||
hasteModuleName,
|
||||
|
||||
Reference in New Issue
Block a user