Skip to content

Commit

Permalink
fix: Use symbol type when there's no baseconstraint (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
eps1lon committed Jun 2, 2020
1 parent 2ac9140 commit 0b170af
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,15 +376,21 @@ export function parseFromProgram(
}
}

let type = declaration
const symbolType = declaration
? // The proptypes aren't detailed enough that we need all the different combinations
// so we just pick the first and ignore the rest
checker.getTypeAtLocation(declaration)
checker.getTypeOfSymbolAtLocation(symbol, declaration)
: // The properties of Record<..., ...> don't have a declaration, but the symbol has a type property
((symbol as any).type as ts.Type);
// get `React.ElementType` from `C extends React.ElementType`
const baseConstraintOfType = checker.getBaseConstraintOfType(type);
type = baseConstraintOfType === undefined ? type : baseConstraintOfType;
const declaredType =
declaration !== undefined ? checker.getTypeAtLocation(declaration) : undefined;
const baseConstraintOfType =
declaredType !== undefined ? checker.getBaseConstraintOfType(declaredType) : undefined;
const type =
baseConstraintOfType !== undefined && baseConstraintOfType !== declaredType
? baseConstraintOfType
: symbolType;

if (!type) {
throw new Error('No types found');
Expand Down
21 changes: 21 additions & 0 deletions test/union-props/input.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as React from 'react';

export interface BaseProps {
value?: unknown;
}

export interface StandardProps extends BaseProps {
variant?: 'standard';
}

export interface OutlinedProps extends BaseProps {
variant: 'outlined';
}

export interface FilledProps extends BaseProps {
variant: 'filled';
}

export type TextFieldProps = StandardProps | OutlinedProps | FilledProps;

export default function TextField(props: TextFieldProps): JSX.Element;
11 changes: 11 additions & 0 deletions test/union-props/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';

export default function TextField(props) {
const { value, variant } = props;

return (
<React.Fragment>
{variant}: <input value={value} />
</React.Fragment>
);
}
19 changes: 19 additions & 0 deletions test/union-props/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import PropTypes from 'prop-types';

function TextField(props) {
const { value, variant } = props;

return (
<React.Fragment>
{variant}: <input value={value} />
</React.Fragment>
);
}

TextField.propTypes = {
value: PropTypes.any,
variant: PropTypes.oneOf(['filled', 'outlined', 'standard']),
};

export default TextField;
34 changes: 34 additions & 0 deletions test/union-props/output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"type": "ProgramNode",
"body": [
{
"type": "ComponentNode",
"name": "TextField",
"types": [
{
"type": "PropTypeNode",
"name": "variant",
"propType": {
"type": "UnionNode",
"types": [
{ "type": "UndefinedNode" },
{ "type": "LiteralNode", "value": "\"standard\"" },
{ "type": "LiteralNode", "value": "\"outlined\"" },
{ "type": "LiteralNode", "value": "\"filled\"" }
]
},
"filenames": {}
},
{
"type": "PropTypeNode",
"name": "value",
"propType": {
"type": "UnionNode",
"types": [{ "type": "UndefinedNode" }, { "type": "AnyNode" }]
},
"filenames": {}
}
]
}
]
}

0 comments on commit 0b170af

Please sign in to comment.