Skip to content

Commit 1a8d118

Browse files
author
k.golikov
committed
Json-to-TypeScript: add object type declaration type option (interface, type)
1 parent 82594da commit 1a8d118

File tree

6 files changed

+46
-16
lines changed

6 files changed

+46
-16
lines changed

src/pages/jsonToTypeScriptPage/JsonToTypeScriptPage.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ import getLocalStorageKey from '../../utils/getLocalStorageKey';
1616
import JsonToTypeScriptConversionSelectableOptions, {
1717
NameTransformer
1818
} from './types/JsonToTypeScriptConversionSelectableOptions';
19-
import JsonToTypeScriptConversionOptions, { NullType, UnknownType } from './types/JsonToTypeScriptConversionOptions';
19+
import JsonToTypeScriptConversionOptions, {
20+
NullType,
21+
ObjectDeclaration,
22+
UnknownType
23+
} from './types/JsonToTypeScriptConversionOptions';
2024
import { camelCase, kebabCase, snakeCase } from 'lodash';
2125
import pascalCase from '../../utils/pascalCase';
2226
import JsonToTypeScriptSettings from './components/JsonToTypeScriptSettings';
@@ -39,7 +43,8 @@ const defaultSelectableConversionOptions: JsonToTypeScriptConversionSelectableOp
3943
fieldNameTransformer: NameTransformer.NONE,
4044
isTuplesEnabled: false,
4145
nullType: NullType.NULL,
42-
unknownType: UnknownType.UNKNOWN
46+
unknownType: UnknownType.UNKNOWN,
47+
objectDeclaration: ObjectDeclaration.INTERFACE
4348
};
4449

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

src/pages/jsonToTypeScriptPage/components/JsonToTypeScriptSettings.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +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';
12+
import { NullType, ObjectDeclaration, UnknownType } from '../types/JsonToTypeScriptConversionOptions';
1313

1414
interface Props {
1515
options: JsonToTypeScriptConversionSelectableOptions;
@@ -101,11 +101,22 @@ const JsonToTypeScriptSettings: FunctionComponent<Props> = ({ options, setOption
101101
<Select.Option key={NullType.UNDEFINED}>undefined</Select.Option>
102102
</Select>
103103
</label>
104+
<label className={styles.formItem}>
105+
<span className={styles.label}>Object declaration</span>
106+
<Select
107+
className={styles.input}
108+
value={options.objectDeclaration}
109+
onChange={handleOptionChange('objectDeclaration')}
110+
>
111+
<Select.Option key={ObjectDeclaration.INTERFACE}>Interface</Select.Option>
112+
<Select.Option key={ObjectDeclaration.TYPE}>Type</Select.Option>
113+
</Select>
114+
</label>
115+
104116
<label className={classNames('mt-1', styles.formItem)}>
105117
<Switch checked={options.isReversedOrder} onChange={handleOptionChange('isReversedOrder')} />
106118
<span className="ms-3">Reverse declarations</span>
107119
</label>
108-
109120
<label className={classNames('mt-1', styles.formItem)}>
110121
<Switch checked={options.isTuplesEnabled} onChange={handleOptionChange('isTuplesEnabled')} />
111122
<Text className="ms-3">

src/pages/jsonToTypeScriptPage/types/JsonToTypeScriptConversionOptions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ export enum UnknownType {
1010
ANY = 'any'
1111
}
1212

13+
export enum ObjectDeclaration {
14+
INTERFACE = 'INTERFACE',
15+
TYPE = 'TYPE'
16+
}
17+
1318
interface JsonToTypeScriptConversionOptions {
1419
exportType?: ExportType;
1520
isReversedOrder?: boolean;
@@ -19,6 +24,7 @@ interface JsonToTypeScriptConversionOptions {
1924
isTuplesEnabled?: boolean;
2025
nullType?: NullType;
2126
unknownType?: UnknownType;
27+
objectDeclaration?: ObjectDeclaration;
2228
}
2329

2430
export default JsonToTypeScriptConversionOptions;

src/pages/jsonToTypeScriptPage/types/typescript.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import getTypeScriptTypeReference from '../utils/getTypeScriptTypeReference';
33
import mapObject from '../../../utils/mapObject';
44
import ExportType from './ExportType';
55
import { filter, isObject, isString } from 'lodash';
6-
import JsonToTypeScriptConversionOptions from './JsonToTypeScriptConversionOptions';
6+
import JsonToTypeScriptConversionOptions, { ObjectDeclaration } from './JsonToTypeScriptConversionOptions';
77
import isValidJsIdentifier, { isValidTsTypeFieldName } from '../../../utils/isValidJsIdentifier';
88

99
export interface ITypeScriptType {
@@ -67,13 +67,22 @@ export class TypeScriptObjectField implements IDeclarable {
6767
}
6868
}
6969

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

7373
stringifyDeclaration(options: JsonToTypeScriptConversionOptions): string {
74-
return `${getExportKeyword(options.exportType)}interface ${this.stringifyReference(
75-
options
76-
)} ${this.stringifyDeclarationBody(options)}`;
74+
const exportKeyword = getExportKeyword(options.exportType);
75+
const name = this.stringifyReference(options);
76+
const declarationBody = this.stringifyDeclarationBody(options);
77+
78+
const declarationType = options.objectDeclaration ?? ObjectDeclaration.INTERFACE;
79+
80+
const declarations: Readonly<Record<ObjectDeclaration, string>> = {
81+
[ObjectDeclaration.INTERFACE]: `${exportKeyword}interface ${name} ${declarationBody}`,
82+
[ObjectDeclaration.TYPE]: `${exportKeyword}type ${name} = ${declarationBody};`
83+
};
84+
85+
return declarations[declarationType];
7786
}
7887

7988
stringifyDeclarationBody(options: JsonToTypeScriptConversionOptions): string {
@@ -130,7 +139,6 @@ export class TypeScriptUnion extends TypeScriptTypesCombination {
130139
}
131140
}
132141

133-
//TODO add tuples support
134142
export class TypeScriptTuple extends TypeScriptTypesCombination {
135143
public constructor(public name: string, public readonly types: TypeScriptType[]) {
136144
super(name, types);
@@ -147,7 +155,7 @@ export class TypeScriptTuple extends TypeScriptTypesCombination {
147155

148156
export type TypeScriptType =
149157
| JsonPrimitive
150-
| TypeScriptInterface
158+
| TypeScriptObject
151159
| TypeScriptArray
152160
| TypeScriptUnion
153161
| TypeScriptTuple

src/pages/jsonToTypeScriptPage/utils/getTypeScriptType.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { JsonArray, JsonType } from '../types/json';
22
import {
33
TypeScriptArray,
4-
TypeScriptInterface,
4+
TypeScriptObject,
55
TypeScriptObjectField,
66
TypeScriptTuple,
77
TypeScriptType,
@@ -51,7 +51,7 @@ const getTypeScriptType = (
5151
}
5252
}
5353

54-
return new TypeScriptInterface(
54+
return new TypeScriptObject(
5555
typeName,
5656
chain(jsonType.fields)
5757
.mapValues((field, name) => {

src/pages/jsonToTypeScriptPage/utils/mergeTypeScriptTypes.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { chain, isString, uniq } from 'lodash';
22
import {
33
TypeScriptArray,
4-
TypeScriptInterface,
4+
TypeScriptObject,
55
TypeScriptObjectField,
66
TypeScriptType,
77
TypeScriptUnion
@@ -21,7 +21,7 @@ const mergeTypeScriptTypes = (
2121
return a === b ? singleType : bothTypes;
2222
}
2323

24-
if (a instanceof TypeScriptInterface && b instanceof TypeScriptInterface) {
24+
if (a instanceof TypeScriptObject && b instanceof TypeScriptObject) {
2525
const aKeys = Object.keys(a.fields);
2626
const bKeys = Object.keys(b.fields);
2727

@@ -61,7 +61,7 @@ const mergeTypeScriptTypes = (
6161
}, {} as Record<string, TypeScriptObjectField>)
6262
.value();
6363

64-
return new TypeScriptInterface(a.name, mergedFields);
64+
return new TypeScriptObject(a.name, mergedFields);
6565
}
6666

6767
if (a instanceof TypeScriptArray && b instanceof TypeScriptArray) {

0 commit comments

Comments
 (0)