Skip to content

Instantly share code, notes, and snippets.

@akkunchoi
Last active May 5, 2018 07:37
Show Gist options
  • Save akkunchoi/b3d1287e37491945ff2fc91a749b68d1 to your computer and use it in GitHub Desktop.
Save akkunchoi/b3d1287e37491945ff2fc91a749b68d1 to your computer and use it in GitHub Desktop.
generate cli help from types
/**
*
* help({fileName: "", typeName: ""})
*
*/
import * as ts from "typescript";
interface HelpParameter {
fileName: string;
typeName: string;
}
interface CliOption {
name: string;
typeString: string;
}
export function doc() {
}
export function help(param: HelpParameter) {
const options = {};
const program = ts.createProgram([param.fileName], options);
const source = program.getSourceFile(param.fileName);
const checker = program.getTypeChecker();
const cliOptions = getCliOptions();
const summary = cliOptions.map((opt: CliOption) => {
return `[--${opt.name}]`;
}).join("")
console.log("usage: ");
console.log(` $ cli-help ${summary}`);
console.log("");
console.log("options: ");
cliOptions.forEach((opt: CliOption) => {
console.log(` ${opt.name}: ${opt.typeString}`);
})
function getCliOptions() {
const symbols: CliOption[] = [];
ts.forEachChild(source, function next(node) {
if (
(ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) &&
node.name
) {
const type = checker.getTypeAtLocation(node);
const ctorSymbol = checker.getSymbolAtLocation(node.name);
if (!ctorSymbol) return;
if (ctorSymbol.name === param.typeName) {
type.getProperties().map((symbol: ts.Symbol) => {
const type = checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration!);
// ts.TypeFormatFlags.AddUndefined が効かない?
symbols.push({
name: symbol.name,
typeString: checker.typeToString(type, undefined, ts.TypeFormatFlags.AddUndefined)
});
});
}
}
});
return symbols;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment