Skip to content

Commit 82594da

Browse files
author
k.golikov
committed
Json-to-TypeScript: add null and unknown options (can be changed to undefined and any)
1 parent 843c0ef commit 82594da

File tree

5 files changed

+71
-33
lines changed

5 files changed

+71
-33
lines changed

src/pages/jsonToTypeScriptPage/JsonToTypeScriptPage.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import getLocalStorageKey from '../../utils/getLocalStorageKey';
1616
import JsonToTypeScriptConversionSelectableOptions, {
1717
NameTransformer
1818
} from './types/JsonToTypeScriptConversionSelectableOptions';
19-
import JsonToTypeScriptConversionOptions from './types/JsonToTypeScriptConversionOptions';
19+
import JsonToTypeScriptConversionOptions, { NullType, UnknownType } from './types/JsonToTypeScriptConversionOptions';
2020
import { camelCase, kebabCase, snakeCase } from 'lodash';
2121
import pascalCase from '../../utils/pascalCase';
2222
import JsonToTypeScriptSettings from './components/JsonToTypeScriptSettings';
@@ -37,7 +37,9 @@ const defaultSelectableConversionOptions: JsonToTypeScriptConversionSelectableOp
3737
isReversedOrder: true,
3838
typeNameTransformer: NameTransformer.PASCAL_CASE,
3939
fieldNameTransformer: NameTransformer.NONE,
40-
isTuplesEnabled: false
40+
isTuplesEnabled: false,
41+
nullType: NullType.NULL,
42+
unknownType: UnknownType.UNKNOWN
4143
};
4244

4345
const nameTransformers: Readonly<Record<NameTransformer, (name: string) => string>> = {

src/pages/jsonToTypeScriptPage/components/JsonToTypeScriptSettings.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import ExportType from '../types/ExportType';
99
import Text from 'antd/lib/typography/Text';
1010
import classNames from 'classnames';
1111
import { CloseOutlined } from '@ant-design/icons';
12+
import { NullType, UnknownType } from '../types/JsonToTypeScriptConversionOptions';
1213

1314
interface Props {
1415
options: JsonToTypeScriptConversionSelectableOptions;
@@ -82,6 +83,24 @@ const JsonToTypeScriptSettings: FunctionComponent<Props> = ({ options, setOption
8283
<Select.Option key={NameTransformer.SCREAMING_SNAKE_CASE}>SCREAMING_SNAKE_CASE</Select.Option>
8384
</Select>
8485
</label>
86+
<label className={styles.formItem}>
87+
<span className={styles.label}>Unknown type</span>
88+
<Select
89+
className={styles.input}
90+
value={options.unknownType}
91+
onChange={handleOptionChange('unknownType')}
92+
>
93+
<Select.Option key={UnknownType.UNKNOWN}>unknown</Select.Option>
94+
<Select.Option key={UnknownType.ANY}>any</Select.Option>
95+
</Select>
96+
</label>
97+
<label className={styles.formItem}>
98+
<span className={styles.label}>Null type</span>
99+
<Select className={styles.input} value={options.nullType} onChange={handleOptionChange('nullType')}>
100+
<Select.Option key={NullType.NULL}>null</Select.Option>
101+
<Select.Option key={NullType.UNDEFINED}>undefined</Select.Option>
102+
</Select>
103+
</label>
85104
<label className={classNames('mt-1', styles.formItem)}>
86105
<Switch checked={options.isReversedOrder} onChange={handleOptionChange('isReversedOrder')} />
87106
<span className="ms-3">Reverse declarations</span>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
import ExportType from './ExportType';
22

3+
export enum NullType {
4+
NULL = 'null',
5+
UNDEFINED = 'undefined'
6+
}
7+
8+
export enum UnknownType {
9+
UNKNOWN = 'unknown',
10+
ANY = 'any'
11+
}
12+
313
interface JsonToTypeScriptConversionOptions {
414
exportType?: ExportType;
515
isReversedOrder?: boolean;
616
fieldNameTransformer?: (fieldName: string) => string;
717
typeNameTransformer?: (typeName: string) => string;
818
rootTypeName: string;
919
isTuplesEnabled?: boolean;
20+
nullType?: NullType;
21+
unknownType?: UnknownType;
1022
}
1123

1224
export default JsonToTypeScriptConversionOptions;

src/pages/jsonToTypeScriptPage/types/typescript.ts

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import JsonToTypeScriptConversionOptions from './JsonToTypeScriptConversionOptio
77
import isValidJsIdentifier, { isValidTsTypeFieldName } from '../../../utils/isValidJsIdentifier';
88

99
export interface ITypeScriptType {
10-
stringifyReference(): string;
10+
stringifyReference(options: JsonToTypeScriptConversionOptions): string;
1111
}
1212

1313
export interface IDeclarable {
14-
stringifyDeclarationBody(): string;
14+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string;
1515
}
1616

1717
export interface IDeclarableTypeScriptType extends IDeclarable {
@@ -35,67 +35,67 @@ export class DeclarableTypeScriptType implements IDeclarableTypeScriptType {
3535

3636
return `${getExportKeyword(options.exportType)}type ${stringifyTypeName(
3737
this.name
38-
)} = ${this.stringifyDeclarationBody()};`;
38+
)} = ${this.stringifyDeclarationBody(options)};`;
3939
}
4040

41-
stringifyDeclarationBody(): string {
41+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
4242
if (isString(this.type)) {
43-
return this.type;
43+
return getTypeScriptTypeReference(this.type, options);
4444
}
4545

4646
return 'stringifyDeclarationBody' in this.type
47-
? this.type.stringifyDeclarationBody()
47+
? this.type.stringifyDeclarationBody(options)
4848
: 'stringifyReference' in this.type
49-
? this.type.stringifyReference()
49+
? this.type.stringifyReference(options)
5050
: '';
5151
}
5252
}
5353

5454
export class TypeScriptUnknown implements ITypeScriptType {
5555
public readonly isUnknown = true;
5656

57-
stringifyReference(): string {
58-
return 'unknown';
57+
stringifyReference(options: JsonToTypeScriptConversionOptions): string {
58+
return options.unknownType ?? 'unknown';
5959
}
6060
}
6161

6262
export class TypeScriptObjectField implements IDeclarable {
6363
public constructor(public readonly type: TypeScriptType, public readonly isOptional = false) {}
6464

65-
stringifyDeclarationBody(): string {
66-
return `${this.isOptional ? '?' : ''}: ${getTypeScriptTypeReference(this.type)}`;
65+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
66+
return `${this.isOptional ? '?' : ''}: ${getTypeScriptTypeReference(this.type, options)}`;
6767
}
6868
}
6969

7070
export class TypeScriptInterface implements ITypeScriptType, IDeclarableTypeScriptType {
7171
public constructor(public name: string, public readonly fields: Record<string, TypeScriptObjectField>) {}
7272

73-
stringifyDeclaration({ exportType }: JsonToTypeScriptConversionOptions): string {
74-
return `${getExportKeyword(
75-
exportType
76-
)}interface ${this.stringifyReference()} ${this.stringifyDeclarationBody()}`;
73+
stringifyDeclaration(options: JsonToTypeScriptConversionOptions): string {
74+
return `${getExportKeyword(options.exportType)}interface ${this.stringifyReference(
75+
options
76+
)} ${this.stringifyDeclarationBody(options)}`;
7777
}
7878

79-
stringifyDeclarationBody(): string {
79+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
8080
return (
8181
'{\n' +
8282
mapObject(this.fields, (key, field) => {
83-
return ` ${stringifyFieldName(key)}${field.stringifyDeclarationBody()};`;
83+
return ` ${stringifyFieldName(key)}${field.stringifyDeclarationBody(options)};`;
8484
}).join('\n') +
8585
'\n}'
8686
);
8787
}
8888

89-
stringifyReference(): string {
89+
stringifyReference(options: JsonToTypeScriptConversionOptions): string {
9090
return stringifyTypeName(this.name);
9191
}
9292
}
9393

9494
export class TypeScriptArray implements ITypeScriptType {
9595
public constructor(public readonly type: TypeScriptType) {}
9696

97-
stringifyReference(): string {
98-
const typeReference = getTypeScriptTypeReference(this.type);
97+
stringifyReference(options: JsonToTypeScriptConversionOptions): string {
98+
const typeReference = getTypeScriptTypeReference(this.type, options);
9999

100100
if (this.type instanceof TypeScriptUnion) {
101101
return `Array<${typeReference}>`;
@@ -108,7 +108,7 @@ export class TypeScriptArray implements ITypeScriptType {
108108
export abstract class TypeScriptTypesCombination implements ITypeScriptType {
109109
protected constructor(public name: string, public readonly types: TypeScriptType[]) {}
110110

111-
abstract stringifyReference(): string;
111+
abstract stringifyReference(options: JsonToTypeScriptConversionOptions): string;
112112
}
113113

114114
export class TypeScriptUnion extends TypeScriptTypesCombination {
@@ -121,12 +121,12 @@ export class TypeScriptUnion extends TypeScriptTypesCombination {
121121
// return `${getExportKeyword(exportType)}type ${this.name} = ${this.stringifyDeclarationBody()};`;
122122
// }
123123

124-
stringifyDeclarationBody(): string {
125-
return this.types.map(getTypeScriptTypeReference).join(' | ');
124+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
125+
return this.types.map((type) => getTypeScriptTypeReference(type, options)).join(' | ');
126126
}
127127

128-
stringifyReference(): string {
129-
return this.stringifyDeclarationBody();
128+
stringifyReference(options: JsonToTypeScriptConversionOptions): string {
129+
return this.stringifyDeclarationBody(options);
130130
}
131131
}
132132

@@ -136,12 +136,12 @@ export class TypeScriptTuple extends TypeScriptTypesCombination {
136136
super(name, types);
137137
}
138138

139-
stringifyDeclarationBody(): string {
140-
return '[' + this.types.map(getTypeScriptTypeReference).join(', ') + ']';
139+
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
140+
return '[' + this.types.map((type) => getTypeScriptTypeReference(type, options)).join(', ') + ']';
141141
}
142142

143-
stringifyReference(): string {
144-
return this.stringifyDeclarationBody();
143+
stringifyReference(options: JsonToTypeScriptConversionOptions): string {
144+
return this.stringifyDeclarationBody(options);
145145
}
146146
}
147147

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import { TypeScriptType } from '../types/typescript';
22
import { isString } from 'lodash';
3+
import JsonToTypeScriptConversionOptions from '../types/JsonToTypeScriptConversionOptions';
34

4-
const getTypeScriptTypeReference = (type: TypeScriptType): string => {
5+
const getTypeScriptTypeReference = (type: TypeScriptType, options: JsonToTypeScriptConversionOptions): string => {
56
if (isString(type)) {
7+
if (type === 'null') {
8+
return options.nullType ?? type;
9+
}
10+
611
return type;
712
}
813

9-
return type.stringifyReference();
14+
return type.stringifyReference(options);
1015
};
1116

1217
export default getTypeScriptTypeReference;

0 commit comments

Comments
 (0)