UNPKG

documentation

Version:
111 lines (95 loc) 2.84 kB
import typeAnnotation from '../type_annotation.js'; import findTarget from './finders.js'; function prefixedName(name, prefix) { if (prefix.length) { return prefix.join('.') + '.' + name; } 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); } else if (property.type === 'TSPropertySignature') { // typescript type = typeAnnotation(property.typeAnnotation); } else if (property.type === 'TSMethodSignature') { // typescript type = typeAnnotation(property); } if (property.key) { name = property.key.name || property.key.value; } // Special handling for { ...$Exact<Type> } 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', expression: type }; } return { title: 'property', name: prefixedName(name, prefix), lineNumber: property.loc.start.line, type }; } /** * Infers properties of TypeAlias objects (Flow or TypeScript type definitions) * * @param {Object} comment parsed comment * @returns {Object} comment with inferred properties */ export default function inferProperties(comment) { const explicitProperties = new Set(); // Ensure that explicitly specified properties are not overridden // by inferred properties comment.properties.forEach(prop => explicitProperties.add(prop.name)); function inferProperties(value, prefix) { if ( value.type === 'ObjectTypeAnnotation' || value.type === 'TSTypeLiteral' ) { const properties = value.properties || value.members || value.body || []; properties.forEach(function (property) { let name; if (property.key) { name = property.key.name; } // Special handling for { ...$Exact<Type> } if (isObjectSpreadAndExactUtilTypeProperty(property)) { name = property.argument.id.name; } if (!explicitProperties.has(prefixedName(name, prefix))) { comment.properties = comment.properties.concat( propertyToDoc(property, prefix) ); } }); } } const path = findTarget(comment.context.ast); if (path) { if (path.isTypeAlias()) { inferProperties(path.node.right, []); } else if (path.isTSTypeAliasDeclaration()) { inferProperties(path.node.typeAnnotation, []); } } return comment; }