Skip to content
This repository was archived by the owner on Sep 21, 2019. It is now read-only.

Commit f047efc

Browse files
author
Mohsen Azimi
committed
Use question mark token for optional props
1 parent 1f4cab9 commit f047efc

File tree

3 files changed

+23
-24
lines changed

3 files changed

+23
-24
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class MyComponent extends React.Component {
3838
```tsx
3939
type MyComponentProps = {
4040
prop1: string;
41-
prop2: number | undefined;
41+
prop2?: number;
4242
}
4343

4444
type MyComponentState = {

src/transforms/react-js-make-props-and-state-transform.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,18 @@ export function reactJSMakePropsAndStateInterfaceTransformFactoryFactory(typeChe
222222
console.warn('Bad value for propType', name, 'at', propertyAssignment.getStart());
223223
return result;
224224
}
225-
const typeValue = getTypeFromReactPropTypeExpression(propertyAssignment.initializer);
226225

227226
// Ignore children, React types have it
228227
if (propertyAssignment.name.getText() === 'children') {
229228
return result;
230229
}
230+
231+
const typeValue = getTypeFromReactPropTypeExpression(propertyAssignment.initializer);
232+
const isOptional = isPropTypeOptional(propertyAssignment.initializer);
231233
const propertySignature = ts.createPropertySignature(
232234
[],
233235
name,
234-
undefined,
236+
isOptional ? ts.createToken(ts.SyntaxKind.QuestionToken): undefined,
235237
typeValue,
236238
undefined,
237239
);
@@ -291,19 +293,16 @@ export function reactJSMakePropsAndStateInterfaceTransformFactoryFactory(typeChe
291293
} else {
292294
result = ts.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);
293295
}
296+
return result;
297+
}
294298

295-
if (!/\.isRequired/.test(text)) {
296-
return makeTypeNodeOptional(result);
297-
} else {
298-
return result;
299-
}
300-
301-
function makeTypeNodeOptional(node: ts.TypeNode) {
302-
return ts.createUnionOrIntersectionTypeNode(ts.SyntaxKind.UnionType, [
303-
node,
304-
ts.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
305-
]);
306-
}
299+
/**
300+
* Decide if node is optional
301+
* @param node React propTypes member node
302+
*/
303+
function isPropTypeOptional(node: ts.PropertyAccessExpression) {
304+
const text = node.getText().replace(/React\.PropTypes\./, '');
305+
return !/\.isRequired/.test(text)
307306
}
308307
};
309308
};

test/react-js-make-props-and-state-transform/static-proptypes-many-props/output.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import * as React from 'react';
22

33
export default class MyComponent extends React.Component<{
4-
any: any | undefined;
5-
array: any[] | undefined;
6-
bool: boolean | undefined;
7-
func: ((...args: any[]) => any) | undefined;
8-
number: number | undefined;
9-
object: object | undefined;
10-
string: string | undefined;
11-
node: (number | string | JSX.Element) | undefined;
12-
element: JSX.Element | undefined;
4+
any?: any;
5+
array?: any[];
6+
bool?: boolean;
7+
func?: (...args: any[]) => any;
8+
number?: number;
9+
object?: object;
10+
string?: string;
11+
node?: number | string | JSX.Element;
12+
element?: JSX.Element;
1313
anyRequired: any;
1414
arrayRequired: any[];
1515
boolRequired: boolean;

0 commit comments

Comments
 (0)