* Get the interface definition of the first argument of the function or class constructor.
(name: string)
| 48 | * Get the interface definition of the first argument of the function or class constructor. |
| 49 | */ |
| 50 | getArg0Interface(name: string): InterfaceDefinition | null { |
| 51 | let interfaceName: string = ""; |
| 52 | |
| 53 | const visit = (node: ts.Node) => { |
| 54 | // if we find a matching function declaration |
| 55 | if ( |
| 56 | ts.isFunctionDeclaration(node) && |
| 57 | node.name?.getText() === name && |
| 58 | node.parameters.length && |
| 59 | node.parameters[0].type && |
| 60 | ts.isTypeReferenceNode(node.parameters[0].type) |
| 61 | ) { |
| 62 | interfaceName = node.parameters[0].type.typeName.getText(); |
| 63 | } |
| 64 | // if we find a matching class declaration |
| 65 | else if (ts.isClassDeclaration(node) && node.name?.getText() === name) { |
| 66 | const constructor = node.members.find((member) => |
| 67 | ts.isConstructorDeclaration(member), |
| 68 | ) as ts.ConstructorDeclaration; |
| 69 | if ( |
| 70 | constructor && |
| 71 | constructor.parameters.length && |
| 72 | constructor.parameters[0].type && |
| 73 | ts.isTypeReferenceNode(constructor.parameters[0].type) |
| 74 | ) { |
| 75 | interfaceName = constructor.parameters[0].type.typeName.getText(); |
| 76 | } |
| 77 | } |
| 78 | // if we find a matching forwardRef declaration |
| 79 | else if (ts.isVariableStatement(node) || ts.isVariableDeclaration(node)) { |
| 80 | const declarations = ts.isVariableStatement(node) |
| 81 | ? node.declarationList.declarations |
| 82 | : [node]; |
| 83 | |
| 84 | declarations.forEach((declaration) => { |
| 85 | if ( |
| 86 | ts.isVariableDeclaration(declaration) && |
| 87 | declaration.name.getText() === name && |
| 88 | declaration.initializer && |
| 89 | ts.isCallExpression(declaration.initializer) && |
| 90 | declaration.initializer.expression.getText() === "React.forwardRef" |
| 91 | ) { |
| 92 | const func = declaration.initializer.arguments[0]; |
| 93 | if ( |
| 94 | ts.isArrowFunction(func) && |
| 95 | func.parameters.length && |
| 96 | func.parameters[0].type && |
| 97 | ts.isTypeReferenceNode(func.parameters[0].type) |
| 98 | ) { |
| 99 | interfaceName = func.parameters[0].type.typeName.getText(); |
| 100 | } |
| 101 | } |
| 102 | }); |
| 103 | } |
| 104 | |
| 105 | ts.forEachChild(node, visit); |
| 106 | }; |
| 107 |
no test coverage detected