Skip to content

Commit e42fcb9

Browse files
authored
Generate types for config-components props (#814)
1 parent 64a358e commit e42fcb9

File tree

2 files changed

+73
-13
lines changed

2 files changed

+73
-13
lines changed

packages/devextreme-react-generator/src/generator.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ describe('mapOption', () => {
392392
nested: [{
393393
isSubscribable: undefined,
394394
name: 'prop1',
395-
type: 'any',
395+
type: 'number',
396396
}],
397397
isSubscribable: undefined,
398398
});

packages/devextreme-react-generator/src/generator.ts

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import {
88
} from 'path';
99

1010
import {
11+
IArrayDescr,
1112
IComplexProp,
1213
ICustomType,
14+
IFunctionDescr,
1315
IModel,
16+
IObjectDescr,
1417
IProp,
1518
ITypeDescr,
1619
IWidget,
@@ -44,12 +47,79 @@ enum BaseTypes {
4447
Number = 'number',
4548
Boolean = 'boolean',
4649
Object = 'object',
50+
Null = 'null',
51+
True = 'true',
52+
False = 'false',
53+
}
54+
55+
function isFunctionDescriptor(typeDescriptor: ITypeDescr): typeDescriptor is IFunctionDescr {
56+
return typeDescriptor.type === 'Function';
57+
}
58+
59+
function isArrayDescriptor(typeDescriptor: ITypeDescr): typeDescriptor is IArrayDescr {
60+
return typeDescriptor.type === 'Array';
61+
}
62+
63+
function isObjectDescriptor(typeDescriptor: ITypeDescr): typeDescriptor is IObjectDescr {
64+
return typeDescriptor.type === 'Object' && (typeDescriptor as IObjectDescr).fields !== undefined;
65+
}
66+
67+
export function convertToBaseType(type: string): BaseTypes {
68+
return BaseTypes[type];
69+
}
70+
71+
export function getComplexOptionType(types: ITypeDescr[]): string | undefined {
72+
function formatTypeDescriptor(typeDescriptor: ITypeDescr): string {
73+
function formatArrayDescriptor(arrayDescriptor: IArrayDescr): string {
74+
const itemTypes = arrayDescriptor.itemTypes?.map((t) => formatTypeDescriptor(t))
75+
.filter((t) => t !== undefined)
76+
.join(' | ')
77+
|| BaseTypes.Any;
78+
return `Array<${itemTypes}>`;
79+
}
80+
81+
function formatFunctionDescriptor(functionDescriptor: IFunctionDescr): string {
82+
const parameters = functionDescriptor.params?.map((p) => `${p.name}: ${getComplexOptionType(p.types) || BaseTypes.Any}`)
83+
.join(', ') || '';
84+
const returnType = (
85+
functionDescriptor.returnValueType && (convertToBaseType(functionDescriptor.returnValueType.type) || (functionDescriptor.returnValueType.type === 'void' && 'void'))
86+
) || BaseTypes.Any;
87+
return `(${parameters}) => ${returnType}`;
88+
}
89+
90+
function formatObjectDescriptor(objectDescriptor: IObjectDescr): string {
91+
const fields = objectDescriptor.fields.map((f) => `${f.name}: ${getComplexOptionType(f.types) || BaseTypes.Any}`);
92+
return fields ? `{ ${fields.join(', ')} }` : BaseTypes.Object;
93+
}
94+
95+
if (isArrayDescriptor(typeDescriptor)) {
96+
return formatArrayDescriptor(typeDescriptor);
97+
}
98+
if (isFunctionDescriptor(typeDescriptor)) {
99+
const result = formatFunctionDescriptor(typeDescriptor);
100+
// TS1385
101+
return `(${result})`;
102+
}
103+
if (isObjectDescriptor(typeDescriptor)) {
104+
return formatObjectDescriptor(typeDescriptor);
105+
}
106+
if (typeDescriptor.acceptableValues !== undefined
107+
&& typeDescriptor.acceptableValues.length > 0) {
108+
return typeDescriptor.acceptableValues.join(' | ');
109+
}
110+
return convertToBaseType(typeDescriptor.type);
111+
}
112+
113+
return types && isNotEmptyArray(types) ? types
114+
.map((t) => formatTypeDescriptor(t))
115+
.filter((t) => t !== undefined)
116+
.join(' | ') : undefined;
47117
}
48118

49119
export function mapSubscribableOption(prop: IProp): ISubscribableOption {
50120
return {
51121
name: prop.name,
52-
type: 'any',
122+
type: getComplexOptionType(prop.types) || BaseTypes.Any,
53123
isSubscribable: prop.isSubscribable || undefined,
54124
};
55125
}
@@ -64,21 +134,11 @@ export function isNestedOptionArray(prop: IProp): boolean {
64134
return isNotEmptyArray(prop.types) && (prop.types[0].type === 'Array');
65135
}
66136

67-
export function convertToBaseType(type: string) {
68-
return BaseTypes[type];
69-
}
70-
71-
export function getComplexOptionType(types: ITypeDescr[]) {
72-
return types && isNotEmptyArray(types) ? types
73-
.filter((t) => convertToBaseType(t.type))
74-
.map((f) => convertToBaseType(f.type)).join(' | ') : undefined;
75-
}
76-
77137
export function mapOption(prop: IProp): IOption {
78138
return isEmptyArray(prop.props)
79139
? {
80140
name: prop.name,
81-
type: 'any',
141+
type: getComplexOptionType(prop.types) || BaseTypes.Any,
82142
isSubscribable: prop.isSubscribable || undefined,
83143

84144
} : {

0 commit comments

Comments
 (0)