diff --git a/packages/babel-plugin-flow-runtime/src/__tests__/__fixtures__/typeAliases/objects/objectWithExactIndexer.js b/packages/babel-plugin-flow-runtime/src/__tests__/__fixtures__/typeAliases/objects/objectWithExactIndexer.js new file mode 100644 index 0000000..120df8c --- /dev/null +++ b/packages/babel-plugin-flow-runtime/src/__tests__/__fixtures__/typeAliases/objects/objectWithExactIndexer.js @@ -0,0 +1,15 @@ +/* @flow */ + +export const input = ` + type Demo = { + foo?: number; + [any]: empty; + }; +`; + +export const expected = ` + import t from "flow-runtime"; + const Demo = t.type("Demo", t.exactObject( + t.property("foo", t.number(), true) + )); +`; diff --git a/packages/babel-plugin-flow-runtime/src/convert.js b/packages/babel-plugin-flow-runtime/src/convert.js index 7a66cee..d701138 100644 --- a/packages/babel-plugin-flow-runtime/src/convert.js +++ b/packages/babel-plugin-flow-runtime/src/convert.js @@ -762,12 +762,21 @@ converters.ObjectTypeAnnotation = (context: ConversionContext, path: NodePath): [[], new Map(), new Map()] ); + const isEmptyObjectTypeIndexer = (path: NodePath) => path.node.type === 'ObjectTypeIndexer' + && path.node.key.type === 'AnyTypeAnnotation' + && path.node.value.type === 'EmptyTypeAnnotation'; + + const indexers = path.get('indexers'); + const body = [ ...path.get('callProperties'), ...properties, - ...path.get('indexers') + ...indexers.filter(path => !isEmptyObjectTypeIndexer(path)) ]; - return context.call(path.node.exact ? 'exactObject' : 'object', ...body.map(item => convert(context, item))); + + const isExactObject = path.node.exact || indexers.some(path => isEmptyObjectTypeIndexer(path)); + + return context.call(isExactObject ? 'exactObject' : 'object', ...body.map(item => convert(context, item))); }; converters.ObjectTypeSpreadProperty = (context: ConversionContext, path: NodePath): Node => {