Skip to content
This repository has been archived by the owner on Jul 8, 2024. It is now read-only.

Commit

Permalink
changed class component typing generation with funcional component ge…
Browse files Browse the repository at this point in the history
…neration
  • Loading branch information
julischuster committed Dec 2, 2021
1 parent 746123b commit f7d2a3d
Showing 1 changed file with 30 additions and 23 deletions.
53 changes: 30 additions & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,25 @@ export interface Options {

export function generate(options: Options, findAll?: boolean): string {
let result: string = '';
let baseType: string = 'React.Component';
let baseType: string = 'React.FC';

const { input, output, isBaseClass, propTypesComposition, imports } = options;
const {input, output, isBaseClass, propTypesComposition, imports} = options;

const componentName = input.substring(input.lastIndexOf('/') + 1, input.lastIndexOf('.'));

const content: string = fs.readFileSync(input, 'utf8');
const [componentInfo, ...childs] = <ComponentInfo[]>parse(content, findAll ? resolver.findAllComponentDefinitions : undefined);
const [componentInfo, ...childs] = (<ComponentInfo[]>parse(content, findAll ? resolver.findAllComponentDefinitions : undefined)).sort((a) => (a.displayName === componentName ? -1 : 1));;
const className = isBaseClass ? Utils.writeGeneric(componentInfo.displayName, 'T = any') : componentInfo.displayName;

const importDefinitions: dom.Import[] = [];
const interfaceDefinitions: dom.InterfaceDeclaration[] = [];
const intersectDefinitions: dom.PropertyDeclaration[] = [];

if (componentInfo) {
const propsIntefaceName = `${componentInfo.displayName}Props`;
const propsDefinition = dom.create.interface(propsIntefaceName, dom.DeclarationFlags.Export);
const propsInterfaceName = `${componentInfo.displayName}Props`;
const propsDefinition = dom.create.interface(propsInterfaceName, dom.DeclarationFlags.Export);
const importDefinition = dom.create.importAll('React', 'react');
const classDefinition = dom.create.class(className, dom.DeclarationFlags.ExportDefault);
const constDefinition = dom.create.const(className, Utils.writeGeneric('React.FC', propsInterfaceName), dom.DeclarationFlags.None);

importDefinitions.push(importDefinition);

Expand All @@ -57,14 +60,14 @@ export function generate(options: Options, findAll?: boolean): string {

if (keys.length > 0) {
keys.forEach(key => {
const prop = { ...props[key], name: key };
const prop = {...props[key], name: key};
if (!prop.type) {
return;
}

const propResult = Utils.generateProp(prop);
if (propResult) {
const { property, interfaces } = propResult;
const {property, interfaces} = propResult;
propsDefinition.members.push(property);
if (interfaces && interfaces.length > 0) {
interfaceDefinitions.push(...interfaces);
Expand All @@ -73,14 +76,14 @@ export function generate(options: Options, findAll?: boolean): string {
});
}

baseType = Utils.writeGeneric('React.Component', isBaseClass ? 'T' : propsIntefaceName);
baseType = Utils.writeGeneric('React.FC', isBaseClass ? 'T' : propsInterfaceName);
interfaceDefinitions.push(propsDefinition);
}

if (childs && childs.length > 0) {
childs.forEach(({displayName, props}) => {
childs.map(({displayName, props}) => {
const propsIntefaceName2 = `${displayName}Props`;
const propsDefinition2 = dom.create.interface(propsIntefaceName2, dom.DeclarationFlags.Export);
const propsDefinition2 = dom.create.interface(propsIntefaceName2, dom.DeclarationFlags.None);
const importDefinition2 = dom.create.importAll('React', 'react');
importDefinitions.push(importDefinition2);
if (imports && imports.length > 0) {
Expand Down Expand Up @@ -108,9 +111,11 @@ export function generate(options: Options, findAll?: boolean): string {
}
// baseType = Utils.writeGeneric('React.Component', isBaseClass ? 'T' : propsIntefaceName);
interfaceDefinitions.push(propsDefinition2);
classDefinition.members.push(dom.create.property(displayName, Utils.writeGeneric('React.Component', propsIntefaceName2)));
intersectDefinitions.push(dom.create.property(displayName, Utils.writeGeneric('React.FC', propsIntefaceName2)));

}
})
});

}

if (propTypesComposition && propTypesComposition.length > 0) {
Expand All @@ -123,17 +128,17 @@ export function generate(options: Options, findAll?: boolean): string {

if (options.extends) {
if (options.extends.import) {
const { from, named } = options.extends.import;
const {from, named} = options.extends.import;
importDefinitions.push(Utils.createImport(from, options.extends.import.default, named));
const baseTypeName = named as string || options.extends.import.default as string;
const genericName = isBaseClass ? 'T' : propsIntefaceName;
const genericName = isBaseClass ? 'T' : propsInterfaceName;
baseType = Utils.writeGeneric(baseTypeName, genericName);
}
}

if (componentInfo.methods) {
/*if (componentInfo.methods) {
componentInfo.methods.forEach(method => {
const { params, returns } = method;
const {params, returns} = method;
const parameters: dom.Parameter[] = [];
if (params && params.length > 0) {
params.forEach(param => {
Expand All @@ -142,19 +147,21 @@ export function generate(options: Options, findAll?: boolean): string {
});
}
const returnType = returns ? returns.type.name : 'any';
classDefinition.members.push(dom.create.method(method.name, parameters, Utils.getType(returnType)));
constDefinition.members.push(dom.create.method(method.name, parameters, Utils.getType(returnType)));
});
}
}*/

result += dom.emit(dom.create.imports(importDefinitions));
interfaceDefinitions.forEach(x => result += dom.emit(x));
classDefinition.baseType = baseType;
result += dom.emit(classDefinition);
constDefinition.type = dom.create.intersection([baseType, dom.create.objectType(intersectDefinitions)]);
result += dom.emit(constDefinition);
result += `
export default ${componentInfo.displayName}`;

if (result) {
const fileName = output || input.split('.')[0] + '.d.ts';
result = prettier.format(result, { parser: 'typescript' });
fs.writeFileSync(fileName, result, { flag: 'w', encoding: 'utf8' });
result = prettier.format(result, {parser: 'typescript'});
fs.writeFileSync(fileName, result, {flag: 'w', encoding: 'utf8'});
return result;
}
}
Expand Down

0 comments on commit f7d2a3d

Please sign in to comment.