Created
May 31, 2021 21:56
-
-
Save g4rcez/5dd4593fcd8ce024ac46180f2d437cfa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import fs from "fs"; | |
import ts from "typescript"; | |
const isType = (node: ts.Node) => | |
ts.isTypeAliasDeclaration(node) || | |
(ts.isInterfaceDeclaration(node) && node.name && node.name); | |
type DocEntry = { | |
name?: string; | |
fileName?: string; | |
documentation?: string; | |
type?: string; | |
constructors?: DocEntry[]; | |
parameters?: DocEntry[]; | |
returnType?: string; | |
}; | |
const output: DocEntry[] = []; | |
const program = ts.createProgram(["./src/types.ts"], { | |
target: ts.ScriptTarget.ES5, | |
module: ts.ModuleKind.CommonJS, | |
}); | |
const checker = program.getTypeChecker(); | |
function visit(node: ts.Node) { | |
if (!isNodeExported(node)) { | |
return; | |
} | |
if (isType(node)) { | |
const NODE: ts.TypeAliasDeclaration = node as never; | |
let symbol = checker.getSymbolAtLocation(NODE.name); | |
if (symbol) { | |
output.push(serializeType(symbol)); | |
} | |
} else if (ts.isModuleDeclaration(node)) { | |
ts.forEachChild(node, visit); | |
} | |
} | |
/** Serialize a symbol into a json object */ | |
function serializeSymbol(symbol: ts.Symbol): DocEntry { | |
return { | |
name: symbol.getName(), | |
documentation: ts.displayPartsToString( | |
symbol.getDocumentationComment(checker) | |
), | |
type: checker.typeToString( | |
checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration!) | |
), | |
}; | |
} | |
function serializeType(symbol: ts.Symbol): DocEntry { | |
let details = serializeSymbol(symbol); | |
let constructorType = checker.getTypeOfSymbolAtLocation( | |
symbol, | |
symbol.valueDeclaration! | |
); | |
console.log(constructorType); | |
details.constructors = constructorType | |
.getConstructSignatures() | |
.map(serializeSignature); | |
return { | |
constructors: details.constructors, | |
documentation: symbol | |
.getDocumentationComment(checker) | |
.map((x) => x.text) | |
.join(" "), | |
fileName: "", | |
name: symbol.name, | |
}; | |
} | |
/** Serialize a class symbol information */ | |
function serializeClass(symbol: ts.Symbol) { | |
let details = serializeSymbol(symbol); | |
// Get the construct signatures | |
let constructorType = checker.getTypeOfSymbolAtLocation( | |
symbol, | |
symbol.valueDeclaration! | |
); | |
details.constructors = constructorType | |
.getConstructSignatures() | |
.map(serializeSignature); | |
return details; | |
} | |
/** Serialize a signature (call or construct) */ | |
function serializeSignature(signature: ts.Signature) { | |
return { | |
parameters: signature.parameters.map(serializeSymbol), | |
returnType: checker.typeToString(signature.getReturnType()), | |
documentation: ts.displayPartsToString( | |
signature.getDocumentationComment(checker) | |
), | |
}; | |
} | |
/** True if this is visible outside this file, false otherwise */ | |
function isNodeExported(node: ts.Node): boolean { | |
return ( | |
(ts.getCombinedModifierFlags(node as ts.Declaration) & | |
ts.ModifierFlags.Export) !== | |
0 || | |
(!!node.parent && node.parent.kind === ts.SyntaxKind.SourceFile) | |
); | |
} | |
for (const sourceFile of program.getSourceFiles()) { | |
if (!sourceFile.isDeclarationFile) { | |
// Walk the tree to search for classes | |
ts.forEachChild(sourceFile, visit); | |
} | |
} | |
fs.writeFileSync("classes.json", JSON.stringify(output, undefined, 4)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment