Extract UnsupportedObjectPropertyValueTypeAnnotationParserError to a throwing function#34917
Extract UnsupportedObjectPropertyValueTypeAnnotationParserError to a throwing function#34917dhruvtailor7 wants to merge 6 commits into
Conversation
Base commit: 629e8e0 |
Base commit: 629e8e0 |
cipolleschi
left a comment
There was a problem hiding this comment.
Hi @dhruvtailor7! Thanks a lot for taking this task and for the amazing job! 👏
I left some comments to suggest further improvements in the codebase. Could you update the PR with these changes? 🙏
| const UnsupportedObjectPropertyTypeToInvalidPropertyValueTypeMap = { | ||
| FunctionTypeAnnotation: 'FunctionTypeAnnotation', | ||
| VoidTypeAnnotation: 'void', | ||
| PromiseTypeAnnotation: 'Promise', | ||
| }; | ||
|
|
||
| function throwUnsupportedObjectPropertyValueTypeAnnotationParserError( | ||
| moduleName, | ||
| propertyValue, | ||
| propertyKey, | ||
| type, | ||
| ) { | ||
| throw new UnsupportedObjectPropertyValueTypeAnnotationParserError( | ||
| moduleName, | ||
| propertyValue, | ||
| propertyKey, | ||
| type, | ||
| ); | ||
| } | ||
|
|
There was a problem hiding this comment.
This can be moved into and error-utils.js file which is shared between typescript and flow. As you can see, the logic is exactly the same.
There was a problem hiding this comment.
Yes, I was waiting for the other PR to be merged first.
| if ( | ||
| propertyTypeAnnotation.type === 'FunctionTypeAnnotation' || | ||
| propertyTypeAnnotation.type === 'PromiseTypeAnnotation' || | ||
| propertyTypeAnnotation.type === 'VoidTypeAnnotation' | ||
| ) { |
There was a problem hiding this comment.
You can use const keys = Object.keys(UnsupportedObjectPropertyTypeToInvalidPropertyValueTypeMap) to obtain an array with all the keys. Then, you can create a new const invalidKeys = new Set(keys); to create a set from it and, finally use the set with something like:
if (invalidKeys.has(propertyTypeAnnotation.type)) {
throw new error
}
This avoids to explicitly list the three items. Imagine that we have to unsupport other objects, we will have to add other OR clauses which is not very elegant. 😉
| propertyKey, | ||
| type, | ||
| ) { | ||
| throw new UnsupportedObjectPropertyValueTypeAnnotationParserError( |
There was a problem hiding this comment.
I will put also the if logic in the function, s we can factor out more code.
Also, we can have a better name. Something like: throwIfPropertyValueTypeIsUnsupported. What do you think?
| 'Promise', | ||
| invalidPropertyValueType, | ||
| ); | ||
| } else { |
There was a problem hiding this comment.
You don't need the else. If the function throws, the execution flow changes, so we can safely remove this indentation! ;)
| const UnsupportedObjectPropertyTypeToInvalidPropertyValueTypeMap = { | ||
| FunctionTypeAnnotation: 'FunctionTypeAnnotation', | ||
| VoidTypeAnnotation: 'void', | ||
| PromiseTypeAnnotation: 'Promise', | ||
| }; | ||
|
|
||
| function throwUnsupportedObjectPropertyValueTypeAnnotationParserError( | ||
| moduleName, | ||
| propertyValue, | ||
| propertyKey, | ||
| type, | ||
| ) { | ||
| throw new UnsupportedObjectPropertyValueTypeAnnotationParserError( | ||
| moduleName, | ||
| propertyValue, | ||
| propertyKey, | ||
| type, | ||
| ); | ||
| } | ||
|
|
There was a problem hiding this comment.
Theoreticaly, this code should appear only in a single place. It is exactly the same of the Flow one. 😉
| if ( | ||
| propertyTypeAnnotation.type === 'FunctionTypeAnnotation' || | ||
| propertyTypeAnnotation.type === 'PromiseTypeAnnotation' || | ||
| propertyTypeAnnotation.type === 'VoidTypeAnnotation' | ||
| ) { | ||
| const invalidPropertyValueType = | ||
| UnsupportedObjectPropertyTypeToInvalidPropertyValueTypeMap[ | ||
| propertyTypeAnnotation.type | ||
| ]; | ||
|
|
||
| throwUnsupportedObjectPropertyValueTypeAnnotationParserError( | ||
| hasteModuleName, | ||
| property.typeAnnotation.typeAnnotation, | ||
| property.key, | ||
| 'Promise', | ||
| invalidPropertyValueType, | ||
| ); | ||
| } else { | ||
| return { | ||
| name: key.name, | ||
| optional, | ||
| typeAnnotation: wrapNullable( | ||
| isPropertyNullable, | ||
| propertyTypeAnnotation, | ||
| ), | ||
| }; | ||
| } |
There was a problem hiding this comment.
with the suggested changes, this code will just become:
throwIfPropertyValueTypeIsUnsupported(/*params*/)
return {
name: key.name,
optional,
typeAnnotation: wrapNullable(
isPropertyNullable,
propertyTypeAnnotation,
),
};There was a problem hiding this comment.
Hello @cipolleschi, I did the suggested changes but after doing them I get an error with flow as typeAnnotation expects a value of type NativeModuleBaseTypeAnnotation but the type returned by wrapNullable is of type NativeModuleTypeAnnotation. This was also the reason i used else statement before.
It was working before due to flow's type refinement because of the if condition and throw statement. I looked into the Flow documentation but couldn’t find a solution to it. Do you have any suggestions on how I should proceed?
There was a problem hiding this comment.
That's... weird. :/
Let's keep the else, then..
|
After the suggested refactoring, it would be great to have some unit tests, ideally, one for each unsupported case + 1 for a supported case where we check that the function does not throw. |
|
@dhruvtailor7 could you also rebase and resolve the conflicts, please? 🙏 |
|
/rebase |
|
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
This pull request was successfully merged by @dhruvtailor7 in aba6be6. When will my fix make it into a release? | Upcoming Releases |
Summary
This PR is a part of #34872.
Extracted the UnsupportedObjectPropertyValueTypeAnnotationParserError in its own throwing function and reuse that function passing a proper type.
Changelog
[Internal] [Changed] - Extract the UnsupportedObjectPropertyValueTypeAnnotationParserError in its own throwing function and reuse that function passing a proper type.
Test Plan
Output of yarn jest react-native-codegen.
