Skip to content

Commit

Permalink
Allow self-referencing/recursive ts types (#2214)
Browse files Browse the repository at this point in the history
  • Loading branch information
chandlerprall authored Aug 9, 2019
1 parent 9fb97b5 commit 9a33fb4
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
17 changes: 16 additions & 1 deletion scripts/babel/proptypes-from-ts-props/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ function resolveArrayTypeToPropTypes(node, state) {
function resolveIdentifierToPropTypes(node, state) {
const typeDefinitions = state.get('typeDefinitions');
const types = state.get('types');
const inflightResolves = state.get('inflightResolves') || new Set();

let identifier;
switch (node.type) {
Expand Down Expand Up @@ -223,7 +224,21 @@ function resolveIdentifierToPropTypes(node, state) {
const identifierDefinition = typeDefinitions[identifier.name];

if (identifierDefinition) {
return getPropTypesForNode(identifierDefinition, true, state);
if (inflightResolves.has(identifier.name)) {
return types.memberExpression(
types.identifier('PropTypes'),
types.identifier('any')
);
}
inflightResolves.add(identifier.name);
state.set('inflightResolves', inflightResolves);

const propType = getPropTypesForNode(identifierDefinition, true, state);

inflightResolves.delete(identifier.name);
state.set('inflightResolves', inflightResolves);

return propType;
} else {
return null;
}
Expand Down
58 changes: 58 additions & 0 deletions scripts/babel/proptypes-from-ts-props/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2361,6 +2361,64 @@ FooComponent.propTypes = {

});

describe('self-referencing types', () => {

it(`doesn't explode on self-referencing interfaces`, () => {
const result = transform(
`
import React, { SFC } from 'react';
interface FooProps {
label: string;
children?: FooProps[];
}
const FooComponent: SFC<FooProps> = () => {
return (<div>Hello World</div>);
}`,
babelOptions
);

expect(result.code).toBe(`import React from 'react';
import PropTypes from "prop-types";
const FooComponent = () => {
return <div>Hello World</div>;
};
FooComponent.propTypes = {
label: PropTypes.string.isRequired,
children: PropTypes.arrayOf(PropTypes.any.isRequired)
};`);
});

it(`doesn't explode on self-referencing types`, () => {
const result = transform(
`
import React, { SFC } from 'react';
type FooProps = {
label: string;
children?: FooProps[];
}
const FooComponent: SFC<FooProps> = () => {
return (<div>Hello World</div>);
}`,
babelOptions
);

expect(result.code).toBe(`import React from 'react';
import PropTypes from "prop-types";
const FooComponent = () => {
return <div>Hello World</div>;
};
FooComponent.propTypes = {
label: PropTypes.string.isRequired,
children: PropTypes.arrayOf(PropTypes.any.isRequired)
};`);
});

});

});

describe('remove types from exports', () => {
Expand Down

0 comments on commit 9a33fb4

Please sign in to comment.