// @flow
import { Node } from 'react';
let node: Node;
to
import { ReactNode } from 'react';
let node: ReactNode;
Previously, rewriting names like this was only supported for unambiguously namespaced references like React.Node to React.ReactNode.
The gist of the changes is:
collect references to imported unqualified type names from packages called react
if we see a rewritable type name and we have already seen an import of it, then we rewrite it
There's two known issues with the current approach:
if there is an unqualified type already imported that collides with one from React, we will still rewrite the import and references to it, but we will now have two imports of the same name as well as ambiguous references to the type at the usage sites
aliased imports are not supported (e.g. import { Node as RNode } from 'react';) and will no-op
I'm not sure if these tradeoffs are acceptable for the goals of the project. They can be worked around with more effort, but a complete solution will require multiple passes over the file (since we will want to find all imports before we make any decisions about which types to rewrite), which is at odds with the current architecture. The current implementation is optimistic that it won't cause collisions and does not check.
Fragment and Children No Longer Renamed
These two types have equivalents in the TypeScript typings. Rewriting these names would break working code of the form
import { Fragment, Children } from 'react';
as both of those identifiers are runtime values with the same name as their corresponding types. There are no React.ReactFragment or React.ReactChildren runtime values, though there are types.
ChildrenArray<T> Replaced with T | T[]
I don't know if TypeScript ever had a type for this, but it doesn't now. If you look at the type definitions for the React.Children object, you'll see they don't bother with an intermediate React-aware children "array" type, and instead just take a union like T | T[]. So now flow-to-ts performs the same mapping, removing any ChildrenArray import entirely.
This PR does a few React-related things.
Unqualified Imports
This PR supports transformations such as
to
Previously, rewriting names like this was only supported for unambiguously namespaced references like
React.Node
toReact.ReactNode
.The gist of the changes is:
react
There's two known issues with the current approach:
import { Node as RNode } from 'react';
) and will no-opI'm not sure if these tradeoffs are acceptable for the goals of the project. They can be worked around with more effort, but a complete solution will require multiple passes over the file (since we will want to find all imports before we make any decisions about which types to rewrite), which is at odds with the current architecture. The current implementation is optimistic that it won't cause collisions and does not check.
Fragment
andChildren
No Longer RenamedThese two types have equivalents in the TypeScript typings. Rewriting these names would break working code of the form
as both of those identifiers are runtime values with the same name as their corresponding types. There are no
React.ReactFragment
orReact.ReactChildren
runtime values, though there are types.ChildrenArray<T>
Replaced withT | T[]
I don't know if TypeScript ever had a type for this, but it doesn't now. If you look at the type definitions for the
React.Children
object, you'll see they don't bother with an intermediate React-aware children "array" type, and instead just take a union likeT | T[]
. So nowflow-to-ts
performs the same mapping, removing anyChildrenArray
import entirely.