(sourceFile)
| 152 | } |
| 153 | |
| 154 | function extractUtilities(sourceFile) { |
| 155 | const functionParts = []; |
| 156 | |
| 157 | ts.forEachChild(sourceFile, node => { |
| 158 | if ( |
| 159 | ts.isExportAssignment(node) && |
| 160 | node.expression && |
| 161 | ts.isObjectLiteralExpression(node.expression) |
| 162 | ) { |
| 163 | const objectLiteral = node.expression; |
| 164 | objectLiteral.properties.forEach(prop => { |
| 165 | if (prop.name) { |
| 166 | const part = []; |
| 167 | const functionName = prop.name.text; |
| 168 | |
| 169 | const args = prop.parameters || prop.initializer?.parameters || []; |
| 170 | const argsString = args.map((param, index) => { |
| 171 | const paramName = param.name.text || (param.dotDotDotToken ? '...args' : 'param'); |
| 172 | const optional = param.questionToken || param.initializer ? '?' : ''; |
| 173 | if (!param.type?.getText() && param.initializer?.getText()) { |
| 174 | throw new Error(`Utility ${functionName} parameter ${paramName} is missing type annotation`); |
| 175 | } |
| 176 | const type = param.type?.getText() || 'any'; |
| 177 | const dotDotDot = param.dotDotDotToken ? '...' : ''; |
| 178 | return `${dotDotDot}${paramName}${optional}: ${type}`; |
| 179 | }); |
| 180 | |
| 181 | const jsDocs = prop.jsDoc ? prop.jsDoc.map(doc => ` ${doc.getText()}`) : []; |
| 182 | |
| 183 | const returnTypeNames = |
| 184 | prop.type?.getText() || |
| 185 | prop.initializer?.type?.getText() || |
| 186 | `ReturnType<typeof utilitiesRegistry.${functionName}>`; |
| 187 | |
| 188 | const typeParameters = prop.typeParameters || prop.initializer?.typeParameters; |
| 189 | const typeParametersString = typeParameters |
| 190 | ? typeParameters |
| 191 | .filter(param => !param.name || param.name.text !== 'Input') |
| 192 | .map(param => param.getText()) |
| 193 | .join(', ') |
| 194 | : ''; |
| 195 | |
| 196 | console.log(`Utility Name: ${functionName}`); |
| 197 | |
| 198 | part.push( |
| 199 | `${jsDocs.join('\n').replace('*/', `* @see {@link utilitiesRegistry.${functionName}} for implementation details\n */`)}`, |
| 200 | ); |
| 201 | |
| 202 | part.push( |
| 203 | ` ${functionName}: CT.MatchesType<Input, CT.InputTypeUtility<typeof utilitiesRegistry.${functionName}>> extends true`, |
| 204 | ); |
| 205 | part.push( |
| 206 | ` ? ${typeParametersString ? `<${typeParametersString}>` : ''}(${argsString.slice(1).join(', ')}) => ${returnTypeNames}`, |
| 207 | ); |
| 208 | part.push( |
| 209 | ` : CT.TypeMismatchError<'${functionName}', Input, CT.InputTypeUtility<typeof utilitiesRegistry.${functionName}>>;`, |
| 210 | ); |
| 211 |
no outgoing calls
no test coverage detected