diff --git a/src/infer/properties.js b/src/infer/properties.js index 5af742042..35399866c 100644 --- a/src/infer/properties.js +++ b/src/infer/properties.js @@ -8,8 +8,17 @@ function prefixedName(name, prefix) { return name; } +function isObjectSpreadAndExactUtilTypeProperty(property) { + return ( + property.type === 'ObjectTypeSpreadProperty' && + property.argument.id.name === '$Exact' + ); +} + function propertyToDoc(property, prefix) { let type; + let name; + if (property.type === 'ObjectTypeProperty') { // flow type = typeAnnotation(property.value); @@ -20,7 +29,20 @@ function propertyToDoc(property, prefix) { // typescript type = typeAnnotation(property); } - const name = property.key.name || property.key.value; + + if (property.key) { + name = property.key.name || property.key.value; + } + + // Special handling for { ...$Exact } + if (isObjectSpreadAndExactUtilTypeProperty(property)) { + name = property.argument.id.name; + type = { + type: 'NameExpression', + name: property.argument.typeParameters.params[0].id.name + }; + } + if (property.optional) { type = { type: 'OptionalType', @@ -54,7 +76,18 @@ function inferProperties(comment) { ) { const properties = value.properties || value.members || value.body || []; properties.forEach(function(property) { - if (!explicitProperties.has(prefixedName(property.key.name, prefix))) { + let name; + + if (property.key) { + name = property.key.name; + } + + // Special handling for { ...$Exact } + if (isObjectSpreadAndExactUtilTypeProperty(property)) { + name = property.argument.id.name; + } + + if (!explicitProperties.has(prefixedName(name, prefix))) { comment.properties = comment.properties.concat( propertyToDoc(property, prefix) );