mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add pre-transform that replaces nullable types with undefined for object types (#50213)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50213 Changelog: [Internal] Reviewed By: huntie Differential Revision: D71730936 fbshipit-source-id: c126d461fda4ab9758a41421d8300dd92a5cd9af
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f760c11f65
commit
a4282a7cc3
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
const replaceNullablePropertiesWithUndefined = require('../replaceNullablePropertiesWithUndefined.js');
|
||||
const {parse, print} = require('hermes-transform');
|
||||
|
||||
const prettierOptions = {parser: 'babel'};
|
||||
|
||||
async function translate(code: string): Promise<string> {
|
||||
const parsed = await parse(code);
|
||||
const result = await replaceNullablePropertiesWithUndefined(parsed);
|
||||
return print(result.ast, result.mutatedCode, prettierOptions);
|
||||
}
|
||||
|
||||
describe('replaceNullablePropertiesWithUndefined', () => {
|
||||
test('should not replace nullable with undefined outside object type definition', async () => {
|
||||
const code = `function foo(arg: ?string) {}`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"function foo(arg: ?string) {}
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('should replace nullable with undefined inside object type definition', async () => {
|
||||
const code = `type Foo = {bar: ?string};`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = { bar: string | undefined };
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('should replace nullable with undefined inside nested object type definition', async () => {
|
||||
const code = `type Foo = {bar: {baz: ?string}};`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = { bar: { baz: string | undefined } };
|
||||
"
|
||||
`);
|
||||
});
|
||||
|
||||
test('should replace nullable with undefined in function inside object type definition', async () => {
|
||||
const code = `type Foo = {bar: (?string) => void};`;
|
||||
const result = await translate(code);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
"type Foo = { bar: (string | undefined) => void };
|
||||
"
|
||||
`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* 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
|
||||
* @oncall react_native
|
||||
*/
|
||||
|
||||
import type {ESNode, TypeAnnotationType} from 'hermes-estree';
|
||||
import type {TransformVisitor} from 'hermes-transform';
|
||||
import type {ParseResult} from 'hermes-transform/dist/transform/parse';
|
||||
import type {TransformASTResult} from 'hermes-transform/dist/transform/transformAST';
|
||||
|
||||
const {transformAST} = require('hermes-transform/dist/transform/transformAST');
|
||||
|
||||
function isInsideObjectTypeProperty(node: TypeAnnotationType) {
|
||||
let current: ESNode = node;
|
||||
while (current) {
|
||||
if (current.type === 'ObjectTypeProperty') {
|
||||
return true;
|
||||
}
|
||||
current = current.parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const visitors: TransformVisitor = context => ({
|
||||
NullableTypeAnnotation(node): void {
|
||||
if (!isInsideObjectTypeProperty(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// $FlowExpectedError[incompatible-call] - UnionTypeAnnotation is not assignable to NullableTypeAnnotation
|
||||
context.replaceNode(node, {
|
||||
type: 'UnionTypeAnnotation',
|
||||
types: [
|
||||
node.typeAnnotation,
|
||||
{
|
||||
type: 'GenericTypeAnnotation',
|
||||
id: {
|
||||
type: 'Identifier',
|
||||
name: 'undefined',
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Replaces all Stringish type references with string
|
||||
*/
|
||||
async function replaceNullablePropertiesWithUndefined(
|
||||
source: ParseResult,
|
||||
): Promise<TransformASTResult> {
|
||||
return transformAST(source, visitors);
|
||||
}
|
||||
|
||||
module.exports = replaceNullablePropertiesWithUndefined;
|
||||
@@ -25,6 +25,7 @@ const preTransforms: Array<PreTransformFn> = [
|
||||
require('./transforms/replaceRequiresWithImports'),
|
||||
require('./transforms/replaceEmptyWithNever'),
|
||||
require('./transforms/replaceStringishWithString'),
|
||||
require('./transforms/replaceNullablePropertiesWithUndefined'),
|
||||
];
|
||||
const postTransforms: Array<PluginObj<mixed>> = [];
|
||||
const prettierOptions = {parser: 'babel'};
|
||||
|
||||
Reference in New Issue
Block a user