Khan / flow-to-ts

Convert flow code to typescript
https://flow-to-ts.netlify.com
394 stars 75 forks source link

React: rewrite unqualified React imports; update Fragment, Children and ChildrenArray transforms. #397

Open seansfkelley opened 5 months ago

seansfkelley commented 5 months ago

This PR does a few React-related things.

Unqualified Imports

This PR supports transformations such as

// @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:

There's two known issues with the current approach:

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.