Skip to content

Commit

Permalink
Support decorators + fix issue related to custom props in functions (a…
Browse files Browse the repository at this point in the history
…tlassian#54)

* fix: Fix decorator support and allow default props to be missing

* test: Add tests to cover addDefaultProps fix

* test: Add a test against decorator support in typescript

* fix: Fix lookup for nested type names

I.e. Texture["foo"]. Previously it returned `[Object object].foo`. Now
it captures the correct name.

* fix: Include `key` field to ´TSTypeReference`

This way array definitions contain keys. Previously this information
wasn't included making it impossible to introspect.

* chore: Add a flow fixme to make the build pass
  • Loading branch information
bebraw authored and Noviny committed Mar 26, 2019
1 parent 914e372 commit ed12374
Show file tree
Hide file tree
Showing 3 changed files with 241 additions and 2 deletions.
168 changes: 168 additions & 0 deletions packages/extract-react-types/__snapshots__/test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3549,6 +3549,9 @@ Object {
"kind": "property",
"optional": false,
"value": Object {
"key": Object {
"kind": "any",
},
"kind": "generic",
"typeParams": Object {
"kind": "typeParams",
Expand All @@ -3575,6 +3578,84 @@ Object {
}
`;

exports[`ts array prop 1`] = `
Object {
"component": Object {
"kind": "generic",
"name": Object {
"kind": "id",
"name": "Schedule",
"type": null,
},
"value": Object {
"kind": "object",
"members": Array [
Object {
"key": Object {
"kind": "id",
"name": "intervals",
},
"kind": "property",
"optional": false,
"value": Object {
"key": Object {
"kind": "any",
},
"kind": "generic",
"typeParams": Object {
"kind": "typeParams",
"params": Array [
Object {
"kind": "object",
"members": Array [
Object {
"key": Object {
"kind": "id",
"name": "begin",
},
"kind": "property",
"optional": false,
"value": Object {
"kind": "generic",
"value": Object {
"kind": "id",
"name": "Interval['begin']",
},
},
},
Object {
"key": Object {
"kind": "id",
"name": "end",
},
"kind": "property",
"optional": false,
"value": Object {
"kind": "generic",
"value": Object {
"kind": "id",
"name": "Interval['end']",
},
},
},
],
},
],
},
"value": Object {
"kind": "id",
"name": "Array",
},
},
},
],
"referenceIdName": "ScheduleProps",
},
},
"kind": "program",
}
`;

exports[`ts boolean 1`] = `
Object {
"component": Object {
Expand Down Expand Up @@ -3645,6 +3726,52 @@ Object {
}
`;

exports[`ts custom prop 1`] = `
Object {
"component": Object {
"kind": "generic",
"name": Object {
"kind": "id",
"name": "Badge",
"type": null,
},
"value": Object {
"kind": "object",
"members": Array [
Object {
"key": Object {
"kind": "id",
"name": "texture",
},
"kind": "property",
"optional": false,
"value": Object {
"kind": "string",
},
},
],
"referenceIdName": "BadgeProps",
},
},
"kind": "program",
}
`;

exports[`ts decorators 1`] = `
Object {
"component": Object {
"kind": "object",
"members": Array [],
"name": Object {
"kind": "id",
"name": "Theme",
"type": null,
},
},
"kind": "program",
}
`;

exports[`ts different React components 1`] = `
Object {
"component": Object {
Expand Down Expand Up @@ -3989,6 +4116,41 @@ Object {
}
`;

exports[`ts nested prop 1`] = `
Object {
"component": Object {
"kind": "generic",
"name": Object {
"kind": "id",
"name": "Badge",
"type": null,
},
"value": Object {
"kind": "object",
"members": Array [
Object {
"key": Object {
"kind": "id",
"name": "texture",
},
"kind": "property",
"optional": false,
"value": Object {
"kind": "generic",
"value": Object {
"kind": "id",
"name": "Texture['src']",
},
},
},
],
"referenceIdName": "BadgeProps",
},
},
"kind": "program",
}
`;

exports[`ts no react component 1`] = `
Object {
"component": undefined,
Expand Down Expand Up @@ -4356,6 +4518,9 @@ Object {
"referenceIdName": "ReactElement",
"types": Array [
Object {
"key": Object {
"kind": "any",
},
"kind": "generic",
"typeParams": Object {
"kind": "typeParams",
Expand All @@ -4373,6 +4538,9 @@ Object {
Object {
"kind": "arrayType",
"type": Object {
"key": Object {
"kind": "any",
},
"kind": "generic",
"typeParams": Object {
"kind": "typeParams",
Expand Down
13 changes: 11 additions & 2 deletions packages/extract-react-types/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ function convertReactComponentFunction(path, context) {
}

function addDefaultProps(props, defaultProps) {
if (!defaultProps) {
return props;
}

defaultProps.forEach(property => {
let ungeneric = resolveFromGeneric(props);
const prop = getProp(ungeneric, property);
Expand Down Expand Up @@ -878,11 +882,14 @@ converters.TSIndexedAccessType = (path, context) => {
return member.value;
}
}

const name = type.value.name || type.value.referenceIdName;

return {
kind: 'generic',
value: {
kind: type.value.kind,
name: `${type.value.name || type.value.referenceIdName}['${indexKey}']`
name: `${name.name || name}['${indexKey}']`
}
};
} else {
Expand Down Expand Up @@ -949,6 +956,7 @@ converters.TSTypeReference = (path, context) /*: K.Generic */ => {
return {
kind: 'generic',
typeParams: convert(typeParameters, context),
key: convert(path.get('key'), context),
value: convert(path.get('typeName'), context)
};
}
Expand Down Expand Up @@ -1426,7 +1434,7 @@ function getContext(
filename /*:? string */,
resolveOptions /*:? Object */
) {
let plugins = ['jsx'];
let plugins = ['jsx', ['decorators', { decoratorsBeforeExport: true }]];
/* eslint-disable-next-line no-param-reassign */
if (!resolveOptions) resolveOptions = {};

Expand All @@ -1447,6 +1455,7 @@ function getContext(
throw new Error('typeSystem must be either "flow" or "typescript"');
}

/* $FlowFixMe - need to update types in babylon-options */
let parserOpts = createBabylonOptions({
stage: 2,
plugins
Expand Down
62 changes: 62 additions & 0 deletions packages/extract-react-types/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,68 @@ const TESTS = [
}
`
},
{
name: 'ts custom prop',
typeSystem: 'typescript',
code: `
interface BadgeProps {
texture: string;
}
function Badge({ texture }: BadgeProps) {}
Badge.f = [];
export default Badge;
`
},
{
name: 'ts nested prop',
typeSystem: 'typescript',
code: `
interface BadgeProps {
texture: Texture["src"];
}
function Badge({ texture }: BadgeProps) {}
export default Badge;
`
},
{
name: 'ts array prop',
typeSystem: 'typescript',
code: `
interface ScheduleProps {
intervals: Array<{
begin: Interval["begin"];
end: Interval["end"];
}>;
}
function Schedule({ intervals }: ScheduleProps) {}
export default Schedule;
`
},
{
name: 'ts decorators',
typeSystem: 'typescript',
code: `
@ObjectType()
export class Theme extends React.Component<{}, {}> {
@Field(_ => ID)
public id!: string;
@Field(_ => Textures)
public fonts!: Textures;
render() {}
}
export default Theme;
`
},
{
name: 'ts boolean',
typeSystem: 'typescript',
Expand Down

0 comments on commit ed12374

Please sign in to comment.