Skip to content

Commit

Permalink
Fix typescript to not use recast and fix flow types
Browse files Browse the repository at this point in the history
  • Loading branch information
danez committed May 4, 2019
1 parent f5b2121 commit 458f24a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 55 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Expand Up @@ -16,6 +16,7 @@ module.exports = {
globals: {
ASTNode: true,
NodePath: true,
$Exact: true,
},
overrides: [
{
Expand Down
24 changes: 19 additions & 5 deletions src/types.js
Expand Up @@ -45,10 +45,12 @@ export type FlowBaseType = {
alias?: string,
};

export type FlowSimpleType = FlowBaseType & {|
name: string,
raw?: string,
|};
export type FlowSimpleType = $Exact<
FlowBaseType & {
name: string,
raw?: string,
},
>;

export type FlowLiteralType = FlowBaseType & {
name: 'literal',
Expand All @@ -63,7 +65,7 @@ export type FlowElementsType = FlowBaseType & {

export type FlowFunctionArgumentType = {
name: string,
type: FlowTypeDescriptor,
type?: FlowTypeDescriptor,
rest?: boolean,
};

Expand All @@ -77,6 +79,17 @@ export type FlowFunctionSignatureType = FlowBaseType & {
},
};

export type TSFunctionSignatureType = FlowBaseType & {
name: 'signature',
type: 'function',
raw: string,
signature: {
arguments: Array<FlowFunctionArgumentType>,
return: FlowTypeDescriptor,
this?: FlowTypeDescriptor,
},
};

export type FlowObjectSignatureType = FlowBaseType & {
name: 'signature',
type: 'object',
Expand All @@ -100,6 +113,7 @@ export type FlowTypeDescriptor =
export type PropDescriptor = {
type?: PropTypeDescriptor,
flowType?: FlowTypeDescriptor,
tsType?: FlowTypeDescriptor,
required?: boolean,
defaultValue?: any,
description?: string,
Expand Down
37 changes: 14 additions & 23 deletions src/utils/__tests__/getTSType-test.js
Expand Up @@ -6,32 +6,23 @@
*
*/

/* global jest, describe, beforeEach, it, expect */
import { expression as expr, statement as stmt } from '../../../tests/utils';
import getTSType from '../getTSType';

jest.disableAutomock();

describe('getTSType', () => {
let expression, statement;
let getTSType;

beforeEach(() => {
getTSType = require('../getTSType').default;
const {
expression: expr,
statement: stmt,
} = require('../../../tests/utils');
expression = code =>
expr(code, undefined, {
filename: 'test.ts',
babelrc: false,
});
statement = code =>
stmt(code, undefined, {
filename: 'test.ts',
babelrc: false,
});
function expression(code) {
return expr(code, {
filename: 'test.ts',
babelrc: false,
});
}
function statement(code) {
return stmt(code, {
filename: 'test.ts',
babelrc: false,
});
}

describe('getTSType', () => {
it('detects simple types', () => {
const simplePropTypes = [
'string',
Expand Down
9 changes: 5 additions & 4 deletions src/utils/getFlowType.js
Expand Up @@ -17,10 +17,11 @@ import getTypeParameters, {
type TypeParameters,
} from '../utils/getTypeParameters';
import type {
FlowTypeDescriptor,
FlowElementsType,
FlowFunctionSignatureType,
FlowObjectSignatureType,
FlowSimpleType,
FlowTypeDescriptor,
} from '../types';

const { namedTypes: t } = types;
Expand Down Expand Up @@ -199,7 +200,7 @@ function handleObjectTypeAnnotation(
return type;
}

function handleInterfaceDeclaration(path: NodePath): FlowElementsType {
function handleInterfaceDeclaration(path: NodePath): FlowSimpleType {
// Interfaces are handled like references which would be documented separately,
// rather than inlined like type aliases.
return {
Expand Down Expand Up @@ -268,7 +269,7 @@ function handleFunctionTypeAnnotation(
name: param.node.name ? param.node.name.name : '',
type: typeAnnotation
? getFlowTypeWithResolvedTypes(typeAnnotation, typeParams)
: null,
: undefined,
});
});

Expand All @@ -280,7 +281,7 @@ function handleFunctionTypeAnnotation(
name: rest.node.name ? rest.node.name.name : '',
type: typeAnnotation
? getFlowTypeWithResolvedTypes(typeAnnotation, typeParams)
: null,
: undefined,
rest: true,
});
}
Expand Down
50 changes: 27 additions & 23 deletions src/utils/getTSType.js
Expand Up @@ -6,26 +6,26 @@
*
* @flow
*/

import types from 'ast-types';
import getPropertyName from './getPropertyName';
import printValue from './printValue';
import recast from 'recast';
import getTypeAnnotation from '../utils/getTypeAnnotation';
import resolveToValue from '../utils/resolveToValue';
import { resolveObjectToNameArray } from '../utils/resolveObjectKeysToArray';
import getTypeParameters, {
type TypeParameters,
} from '../utils/getTypeParameters';
import type {
FlowTypeDescriptor,
FlowElementsType,
FlowFunctionSignatureType,
FlowFunctionArgumentType,
FlowObjectSignatureType,
FlowSimpleType,
FlowTypeDescriptor,
TSFunctionSignatureType,
} from '../types';

const {
types: { namedTypes: types },
} = recast;
const { namedTypes: t } = types;

const tsTypes = {
TSAnyKeyword: 'any',
Expand Down Expand Up @@ -71,7 +71,7 @@ function handleTSTypeReference(
typeParams: ?TypeParameters,
): ?FlowTypeDescriptor {
let type: FlowTypeDescriptor;
if (types.TSQualifiedName.check(path.node.typeName)) {
if (t.TSQualifiedName.check(path.node.typeName)) {
const typeName = path.get('typeName');

if (typeName.node.left.name === 'React') {
Expand Down Expand Up @@ -144,19 +144,23 @@ function handleTSTypeLiteral(

path.get('members').each(param => {
if (
types.TSPropertySignature.check(param.node) ||
types.TSMethodSignature.check(param.node)
t.TSPropertySignature.check(param.node) ||
t.TSMethodSignature.check(param.node)
) {
const propName = getPropertyName(param);
if (!propName) {
return;
}
type.signature.properties.push({
key: getPropertyName(param),
key: propName,
value: getTSTypeWithRequirements(
param.get('typeAnnotation'),
typeParams,
),
});
} else if (types.TSCallSignatureDeclaration.check(param.node)) {
} else if (t.TSCallSignatureDeclaration.check(param.node)) {
type.signature.constructor = handleTSFunctionType(param, typeParams);
} else if (types.TSIndexSignature.check(param.node)) {
} else if (t.TSIndexSignature.check(param.node)) {
type.signature.properties.push({
key: getTSTypeWithResolvedTypes(
param
Expand All @@ -176,7 +180,7 @@ function handleTSTypeLiteral(
return type;
}

function handleTSInterfaceDeclaration(path: NodePath): FlowElementsType {
function handleTSInterfaceDeclaration(path: NodePath): FlowSimpleType {
// Interfaces are handled like references which would be documented separately,
// rather than inlined like type aliases.
return {
Expand Down Expand Up @@ -213,8 +217,8 @@ function handleTSIntersectionType(
function handleTSFunctionType(
path: NodePath,
typeParams: ?TypeParameters,
): FlowFunctionSignatureType {
const type: FlowFunctionSignatureType = {
): TSFunctionSignatureType {
const type: TSFunctionSignatureType = {
name: 'signature',
type: 'function',
raw: printValue(path),
Expand All @@ -233,7 +237,7 @@ function handleTSFunctionType(
name: param.node.name || '',
type: typeAnnotation
? getTSTypeWithResolvedTypes(typeAnnotation, typeParams)
: null,
: undefined,
};

if (param.node.name === 'this') {
Expand Down Expand Up @@ -284,13 +288,13 @@ function handleTSTypeQuery(
return { name: path.node.exprName.name };
}

function handleTSTypeOperator(path: NodePath): FlowTypeDescriptor {
function handleTSTypeOperator(path: NodePath): ?FlowTypeDescriptor {
if (path.node.operator !== 'keyof') {
return null;
}

let value = path.get('typeAnnotation');
if (types.TSTypeQuery.check(value.node)) {
if (t.TSTypeQuery.check(value.node)) {
value = value.get('exprName');
} else if (value.node.id) {
value = value.get('id');
Expand All @@ -299,8 +303,8 @@ function handleTSTypeOperator(path: NodePath): FlowTypeDescriptor {
const resolvedPath = resolveToValue(value);
if (
resolvedPath &&
(types.ObjectExpression.check(resolvedPath.node) ||
types.TSTypeLiteral.check(resolvedPath.node))
(t.ObjectExpression.check(resolvedPath.node) ||
t.TSTypeLiteral.check(resolvedPath.node))
) {
const keys = resolveObjectToNameArray(resolvedPath, true);

Expand All @@ -320,13 +324,13 @@ function getTSTypeWithResolvedTypes(
path: NodePath,
typeParams: ?TypeParameters,
): FlowTypeDescriptor {
if (types.TSTypeAnnotation.check(path.node)) {
if (t.TSTypeAnnotation.check(path.node)) {
path = path.get('typeAnnotation');
}

const node = path.node;
let type: ?FlowTypeDescriptor;
const isTypeAlias = types.TSTypeAliasDeclaration.check(path.parentPath.node);
const isTypeAlias = t.TSTypeAliasDeclaration.check(path.parentPath.node);

// When we see a typealias mark it as visited so that the next
// call of this function does not run into an endless loop
Expand All @@ -345,7 +349,7 @@ function getTSTypeWithResolvedTypes(

if (node.type in tsTypes) {
type = { name: tsTypes[node.type] };
} else if (types.TSLiteralType.check(node)) {
} else if (t.TSLiteralType.check(node)) {
type = {
name: 'literal',
value: node.literal.raw || `${node.literal.value}`,
Expand Down

0 comments on commit 458f24a

Please sign in to comment.