diff --git a/src/__tests__/data/StatelessWithDefaultPropsAsString.tsx b/src/__tests__/data/StatelessWithDefaultPropsAsString.tsx
new file mode 100644
index 00000000..9a13791d
--- /dev/null
+++ b/src/__tests__/data/StatelessWithDefaultPropsAsString.tsx
@@ -0,0 +1,30 @@
+import * as React from 'react';
+
+/** StatelessWithDefaultProps props */
+export interface StatelessWithDefaultPropsAsStringProps {
+ /** sampleTrue description */
+ sampleTrue?: boolean;
+ /** sampleFalse description */
+ sampleFalse?: boolean;
+ /** sampleNumberWithPrefix description */
+ sampleNumberWithPrefix?: number;
+ /** sampleNumber description */
+ sampleNumber?: number;
+ /** sampleNull description */
+ sampleNull?: null;
+ /** sampleUndefined description */
+ sampleUndefined?: undefined;
+}
+
+export const StatelessWithDefaultPropsAsString: React.StatelessComponent<
+ StatelessWithDefaultPropsAsStringProps
+> = props =>
test
;
+
+StatelessWithDefaultPropsAsString.defaultProps = {
+ sampleFalse: false,
+ sampleNumberWithPrefix: -1,
+ sampleNumber: 1,
+ sampleTrue: true,
+ sampleNull: null,
+ sampleUndefined: undefined
+};
diff --git a/src/__tests__/parser.ts b/src/__tests__/parser.ts
index d031fb3f..6e53cfa6 100644
--- a/src/__tests__/parser.ts
+++ b/src/__tests__/parser.ts
@@ -267,12 +267,12 @@ describe('parser', () => {
type: '"hello" | "goodbye"'
},
sampleFalse: {
- defaultValue: 'false',
+ defaultValue: false,
required: false,
type: 'boolean'
},
- sampleNull: { type: 'null', required: false, defaultValue: 'null' },
- sampleNumber: { type: 'number', required: false, defaultValue: '-1' },
+ sampleNull: { type: 'null', required: false, defaultValue: null },
+ sampleNumber: { type: 'number', required: false, defaultValue: -1 },
sampleObject: {
defaultValue: `{ a: '1', b: 2, c: true, d: false, e: undefined, f: null, g: { a: '1' } }`,
required: false,
@@ -283,7 +283,7 @@ describe('parser', () => {
required: false,
type: 'string'
},
- sampleTrue: { type: 'boolean', required: false, defaultValue: 'true' },
+ sampleTrue: { type: 'boolean', required: false, defaultValue: true },
sampleUndefined: {
defaultValue: 'undefined',
required: false,
@@ -401,12 +401,12 @@ describe('parser', () => {
type: 'enumSample'
},
sampleFalse: {
- defaultValue: 'false',
+ defaultValue: false,
required: false,
type: 'boolean'
},
- sampleNull: { type: 'null', required: false, defaultValue: 'null' },
- sampleNumber: { type: 'number', required: false, defaultValue: '-1' },
+ sampleNull: { type: 'null', required: false, defaultValue: null },
+ sampleNumber: { type: 'number', required: false, defaultValue: -1 },
sampleObject: {
defaultValue: `{ a: '1', b: 2, c: true, d: false, e: undefined, f: null, g: { a: '1' } }`,
required: false,
@@ -417,9 +417,9 @@ describe('parser', () => {
required: false,
type: 'string'
},
- sampleTrue: { type: 'boolean', required: false, defaultValue: 'true' },
+ sampleTrue: { type: 'boolean', required: false, defaultValue: true },
sampleUndefined: {
- defaultValue: 'undefined',
+ defaultValue: undefined,
required: false,
type: 'any'
}
@@ -446,7 +446,7 @@ describe('parser', () => {
type: 'string'
},
shorthandProp: {
- defaultValue: '123',
+ defaultValue: 123,
description: 'shorthandProp description',
required: false,
type: 'number'
@@ -803,6 +803,53 @@ describe('parser', () => {
);
});
});
+
+ describe('Returning not string default props ', () => {
+ it('returns not string defaultProps', () => {
+ check(
+ 'StatelessWithDefaultPropsAsString',
+ {
+ StatelessWithDefaultPropsAsString: {
+ sampleFalse: {
+ defaultValue: 'false',
+ required: false,
+ type: 'boolean'
+ },
+ sampleNumberWithPrefix: {
+ type: 'number',
+ required: false,
+ defaultValue: '-1'
+ },
+ sampleNumber: {
+ type: 'number',
+ required: false,
+ defaultValue: '1'
+ },
+ sampleTrue: {
+ type: 'boolean',
+ required: false,
+ defaultValue: 'true'
+ },
+ sampleNull: {
+ type: 'null',
+ required: false,
+ defaultValue: 'null'
+ },
+ sampleUndefined: {
+ type: 'undefined',
+ required: false,
+ defaultValue: 'undefined'
+ }
+ }
+ },
+ true,
+ null,
+ {
+ savePropValueAsString: true
+ }
+ );
+ });
+ });
});
describe('withCustomConfig', () => {
diff --git a/src/__tests__/testUtils.ts b/src/__tests__/testUtils.ts
index a1f03158..49d7a7bc 100644
--- a/src/__tests__/testUtils.ts
+++ b/src/__tests__/testUtils.ts
@@ -20,7 +20,7 @@ export interface ExpectedProp {
type: string;
required?: boolean;
description?: string;
- defaultValue?: string | null;
+ defaultValue?: string | number | boolean | null | undefined;
parent?: {
name: string;
fileName: string;
diff --git a/src/parser.ts b/src/parser.ts
index 95c0681a..397057f0 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -79,6 +79,7 @@ export interface ParserOptions {
propFilter?: StaticPropFilter | PropFilter;
componentNameResolver?: ComponentNameResolver;
shouldExtractLiteralValuesFromEnum?: boolean;
+ savePropValueAsString?: boolean;
}
export interface StaticPropFilter {
@@ -135,7 +136,9 @@ export function withCustomConfig(
);
if (error !== undefined) {
- const errorText = `Cannot load custom tsconfig.json from provided path: ${tsconfigPath}, with error code: ${error.code}, message: ${error.messageText}`;
+ const errorText = `Cannot load custom tsconfig.json from provided path: ${tsconfigPath}, with error code: ${
+ error.code
+ }, message: ${error.messageText}`;
throw new Error(errorText);
}
@@ -196,13 +199,16 @@ export class Parser {
private checker: ts.TypeChecker;
private propFilter: PropFilter;
private shouldExtractLiteralValuesFromEnum: boolean;
+ private savePropValueAsString: boolean;
constructor(program: ts.Program, opts: ParserOptions) {
+ const { savePropValueAsString, shouldExtractLiteralValuesFromEnum } = opts;
this.checker = program.getTypeChecker();
this.propFilter = buildFilter(opts);
this.shouldExtractLiteralValuesFromEnum = Boolean(
- opts.shouldExtractLiteralValuesFromEnum
+ shouldExtractLiteralValuesFromEnum
);
+ this.savePropValueAsString = Boolean(savePropValueAsString);
}
public getComponentInfo(
@@ -715,7 +721,7 @@ export class Parser {
public getLiteralValueFromPropertyAssignment(
property: ts.PropertyAssignment | ts.BindingElement
- ): string | null {
+ ): string | boolean | number | null | undefined {
let { initializer } = property;
// Shorthand properties, so inflect their actual value
@@ -732,7 +738,7 @@ export class Parser {
}
if (!initializer) {
- return null;
+ return undefined;
}
// Literal values
@@ -740,17 +746,21 @@ export class Parser {
case ts.SyntaxKind.PropertyAccessExpression:
return initializer.getText();
case ts.SyntaxKind.FalseKeyword:
- return 'false';
+ return this.savePropValueAsString ? 'false' : false;
case ts.SyntaxKind.TrueKeyword:
- return 'true';
+ return this.savePropValueAsString ? 'true' : true;
case ts.SyntaxKind.StringLiteral:
return (initializer as ts.StringLiteral).text.trim();
case ts.SyntaxKind.PrefixUnaryExpression:
- return initializer.getFullText().trim();
+ return this.savePropValueAsString
+ ? initializer.getFullText().trim()
+ : Number((initializer as ts.PrefixUnaryExpression).getFullText());
case ts.SyntaxKind.NumericLiteral:
- return `${(initializer as ts.NumericLiteral).text}`;
+ return this.savePropValueAsString
+ ? `${(initializer as ts.NumericLiteral).text}`
+ : Number((initializer as ts.NumericLiteral).text);
case ts.SyntaxKind.NullKeyword:
- return 'null';
+ return this.savePropValueAsString ? 'null' : null;
case ts.SyntaxKind.Identifier:
// can potentially find other identifiers in the source and map those in the future
return (initializer as ts.Identifier).text === 'undefined'
@@ -766,7 +776,7 @@ export class Parser {
public getPropMap(
properties: ts.NodeArray
- ): StringIndexedObject {
+ ): StringIndexedObject {
const propMap = properties.reduce(
(acc, property) => {
if (ts.isSpreadAssignment(property) || !property.name) {
@@ -778,14 +788,21 @@ export class Parser {
);
const propertyName = getPropertyName(property.name);
- if (typeof literalValue === 'string' && propertyName !== null) {
+ if (
+ (typeof literalValue === 'string' ||
+ typeof literalValue === 'number' ||
+ typeof literalValue === 'boolean' ||
+ literalValue === null) &&
+ propertyName !== null
+ ) {
acc[propertyName] = literalValue;
}
return acc;
},
- {} as StringIndexedObject
+ {} as StringIndexedObject
);
+
return propMap;
}
}