react-docgen-typescript
Advanced tools
Comparing version
@@ -293,2 +293,14 @@ "use strict"; | ||
}); | ||
it('should parse react stateless component default props when declared as a normal function', function () { | ||
testUtils_1.check('FunctionDeclarationDefaultProps', { | ||
FunctionDeclarationDefaultProps: { | ||
id: { | ||
defaultValue: 1, | ||
description: '', | ||
required: false, | ||
type: 'number' | ||
} | ||
} | ||
}); | ||
}); | ||
it('should parse react stateless component with external intersection props', function () { | ||
@@ -309,2 +321,39 @@ testUtils_1.check('StatelessIntersectionExternalProps', { | ||
}); | ||
it('should parse react stateless component with intersection + union props', function () { | ||
testUtils_1.check('SimpleUnionIntersection', { | ||
SimpleUnionIntersection: { | ||
bar: { type: 'string', description: '' }, | ||
baz: { type: 'string', description: '' }, | ||
foo: { type: 'string', description: '' } | ||
} | ||
}); | ||
}); | ||
it('should parse react stateless component with intersection + union overlap props', function () { | ||
testUtils_1.check('SimpleDiscriminatedUnionIntersection', { | ||
SimpleDiscriminatedUnionIntersection: { | ||
bar: { type: '"one" | "other"', description: '' }, | ||
baz: { type: 'number', description: '' }, | ||
foo: { type: 'string', description: '' }, | ||
test: { type: 'number', description: '' } | ||
} | ||
}); | ||
}); | ||
it('should parse react stateless component with generic intersection + union overlap props', function () { | ||
testUtils_1.check('ComplexGenericUnionIntersection', { | ||
ComplexGenericUnionIntersection: { | ||
as: { type: 'T', description: '' }, | ||
foo: { | ||
description: 'The foo prop should not repeat the description \nThe foo prop should not repeat the description', | ||
required: false, | ||
type: '"red" | "blue"' | ||
}, | ||
gap: { | ||
description: 'The space between children \nYou cannot use gap when using a "space" justify property', | ||
required: false, | ||
type: 'number' | ||
}, | ||
hasWrap: { type: 'boolean', description: '', required: false } | ||
} | ||
}); | ||
}); | ||
it('should parse react stateful component with intersection props', function () { | ||
@@ -410,2 +459,9 @@ testUtils_1.check('StatefulIntersectionProps', { | ||
}); | ||
it('should parse components with unioned types', function () { | ||
testUtils_1.check('OnlyDefaultExportUnion', { | ||
OnlyDefaultExportUnion: { | ||
content: { description: 'The content', type: 'string' } | ||
} | ||
}); | ||
}); | ||
it('should parse jsdocs with the @default tag and no description', function () { | ||
@@ -412,0 +468,0 @@ testUtils_1.check('StatelessWithDefaultOnlyJsDoc', { |
@@ -80,2 +80,6 @@ "use strict"; | ||
exports.withCompilerOptions = withCompilerOptions; | ||
var isOptional = function (prop) { | ||
// tslint:disable-next-line:no-bitwise | ||
return (prop.getFlags() & ts.SymbolFlags.Optional) !== 0; | ||
}; | ||
var defaultJSDoc = { | ||
@@ -103,16 +107,21 @@ description: '', | ||
if (!exp.valueDeclaration) { | ||
if (!typeSymbol) { | ||
if (exp.getName() === 'default' && !typeSymbol) { | ||
commentSource = this.checker.getAliasedSymbol(commentSource); | ||
} | ||
else if (!typeSymbol) { | ||
return null; | ||
} | ||
exp = typeSymbol; | ||
var expName = exp.getName(); | ||
if (expName === 'StatelessComponent' || | ||
expName === 'Stateless' || | ||
expName === 'StyledComponentClass' || | ||
expName === 'StyledComponent' || | ||
expName === 'FunctionComponent') { | ||
commentSource = this.checker.getAliasedSymbol(commentSource); | ||
} | ||
else { | ||
commentSource = exp; | ||
exp = typeSymbol; | ||
var expName = exp.getName(); | ||
if (expName === 'StatelessComponent' || | ||
expName === 'Stateless' || | ||
expName === 'StyledComponentClass' || | ||
expName === 'StyledComponent' || | ||
expName === 'FunctionComponent') { | ||
commentSource = this.checker.getAliasedSymbol(commentSource); | ||
} | ||
else { | ||
commentSource = exp; | ||
} | ||
} | ||
@@ -312,6 +321,7 @@ } | ||
var propsType = this.checker.getTypeOfSymbolAtLocation(propsObj, propsObj.valueDeclaration); | ||
var propertiesOfProps = propsType.getProperties(); | ||
if (!propertiesOfProps.length && propsType.isUnionOrIntersection()) { | ||
propertiesOfProps = propsType.types.reduce(function (acc, type) { return acc.concat(type.getProperties()); }, []); | ||
} | ||
var baseProps = propsType.getProperties(); | ||
var propertiesOfProps = propsType.isUnionOrIntersection() | ||
? // Using internal typescript API to get all properties | ||
this.checker.getAllPossiblePropertiesOfTypes(propsType.types) | ||
: baseProps; | ||
var result = {}; | ||
@@ -322,4 +332,2 @@ propertiesOfProps.forEach(function (prop) { | ||
var propType = _this.checker.getTypeOfSymbolAtLocation(prop, propsObj.valueDeclaration); | ||
// tslint:disable-next-line:no-bitwise | ||
var isOptional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0; | ||
var jsDocComment = _this.findDocComment(prop); | ||
@@ -335,2 +343,10 @@ var hasCodeBasedDefault = defaultProps[propName] !== undefined; | ||
var parent = getParentType(prop); | ||
var declarations = prop.declarations || []; | ||
var baseProp = baseProps.find(function (p) { return p.getName() === propName; }); | ||
var required = !isOptional(prop) && | ||
!hasCodeBasedDefault && | ||
// If in a intersection or union check original declaration for "?" | ||
// @ts-ignore | ||
declarations.every(function (d) { return !d.questionToken; }) && | ||
(!baseProp || !isOptional(baseProp)); | ||
result[propName] = { | ||
@@ -341,3 +357,3 @@ defaultValue: defaultValue, | ||
parent: parent, | ||
required: !isOptional && !hasCodeBasedDefault, | ||
required: required, | ||
type: _this.getDocgenType(propType) | ||
@@ -418,8 +434,3 @@ }; | ||
return _this.checker.getSymbolAtLocation(stmt.name) === symbol; | ||
}); | ||
if (!possibleStatements.length) { | ||
// if no class declaration is found, try to find a | ||
// expression statement used in a React.StatelessComponent | ||
possibleStatements = source.statements.filter(function (stmt) { return ts.isExpressionStatement(stmt) || ts.isVariableStatement(stmt); }); | ||
} | ||
}).concat(source.statements.filter(function (stmt) { return ts.isExpressionStatement(stmt) || ts.isVariableStatement(stmt); })); | ||
return possibleStatements.reduce(function (res, statement) { | ||
@@ -467,2 +478,4 @@ if (statementIsClassDeclaration(statement) && statement.members.length) { | ||
} | ||
else { | ||
} | ||
var functionStatement = _this.getFunctionStatement(statement); | ||
@@ -469,0 +482,0 @@ // Extracting default values from props destructuring |
{ | ||
"name": "react-docgen-typescript", | ||
"version": "1.16.3", | ||
"version": "1.16.4", | ||
"description": "", | ||
@@ -25,3 +25,5 @@ "homepage": "https://github.com/styleguidist/react-docgen-typescript/", | ||
"license": "MIT", | ||
"dependencies": {}, | ||
"peerDependencies": { | ||
"typescript": ">= 3.x" | ||
}, | ||
"devDependencies": { | ||
@@ -33,3 +35,3 @@ "@types/chai": "^4.1.0", | ||
"@types/prop-types": "^15.5.4", | ||
"@types/react": "^16.4.7", | ||
"@types/react": "^16.9.34", | ||
"@types/source-map-support": "^0.4.1", | ||
@@ -36,0 +38,0 @@ "chai": "^4.1.2", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
162964
3.15%2156
3.31%1
Infinity%