To customise your rendering output, you can extend existing quicktype classes and override existing methods to achieve the behaviour you want.
This process requires 3 main steps:
- Extending a
Renderer
Class - Wrapping your
Renderer
in aTargetLanguage
Class - Using your new classes in the
quicktype
function - Advanced Usage: Creating an entirely new Language
Adding custom render logic for an existing language often involves extending a Renderer class and simply overriding or amending one of the emit
methods:
// MyCustomRenderer.ts
import { CSharpRenderer } from "quicktype-core";
export class MyCustomRenderer extends CSharpRenderer {
// Add your custom logic here, feel free to reference the source code for how existing methods work
//
// ex.
protected superclassForType(t: Type): Sourcelike | undefined {
// if the type is a class, it should extend `GameObject` when rendered in C#
if (t instanceof ClassType) {
return "GameObject";
}
return undefined;
}
// See: http://blog.quicktype.io/customizing-quicktype/ for more context
}
If you just want to change the rendering logic for an existing language, you can just extend an exported Language class (CSharpTargetLanguage
in this example) and override the makeRenderer
method:
// MyCustomLanguage.ts
import { CSharpTargetLanguage } from "quicktype-core";
import { MyCustomRenderer } from "./MyCustomRenderer";
export class MyCustomLanguage extends CSharpTargetLanguage {
// `makeRenderer` instantiates the Renderer class for the TargetLanguage
protected makeRenderer(
renderContext: RenderContext,
untypedOptionValues: Record<string, unknown>
): MyCustomRenderer {
// use your new custom renderer class here
return new MyCustomRenderer(this, renderContext, getOptionValues(cSharpOptions, untypedOptionValues));
}
}
import { quicktype } from "quicktype-core";
import { MyCustomLanguage } from './MyCustomLanguage';
const lang = new MyCustomLanguage();
const lines = await quicktype({
lang: lang, // use your new TargetLanguage in the `lang` field here
...
});
console.log(lines);
If none of the existing quicktype
Language classes suit your needs, you can creating your own TargetLanguge
and Renderer
classes from scratch. If this satisfies your use cases for a language we don't currently support, please consider opening a PR with your new language and we'd love to take a look.
If you run into any issues, you can open a GitHub issue and we'll help you take a look.
Instead of just extending an existing language, a new Language requires two additional steps:
- Defining the language config
- Adding any language-specific options
import { TargetLanguage, BooleanOption } from "quicktype-core";
// language config
const brandNewLanguageConfig = {
displayName: "Scratch", // these can be the same
names: ["scratch"], // these can be the same
extension: "sb" // the file extension that this language commonly has
} as const;
// language options
const brandNewLanguageOptions = {
allowFoo: new BooleanOption(
"allow-foo", // option name
"Allows Foo", // description
true // default value
)
// The default available Option classes are: StringOption, BooleanOption, EnumOption
// Please visit the source code for more examples and usage
};
class BrandNewLanguage extends TargetLanguage<typeof brandNewLanguageConfig> {
public constructor() {
super(brandNewLanguageConfig);
}
public getOptions(): typeof brandNewLanguageOptions {
return brandNewLanguageOptions;
}
protected makeRenderer(
renderContext: RenderContext,
untypedOptionValues: Record<string, unknown>
): BrandNewRenderer {
return new BrandNewRenderer(this, renderContext, getOptionValues(brandNewLanguageOptions, untypedOptionValues));
}
}
Creating a brand new Renderer
class is very similar to extending an existing class:
export class BrandNewRenderer extends ConvenienceRenderer {
public constructor(targetLanguage: TargetLanguage, renderContext: RenderContext) {
super(targetLanguage, renderContext);
}
// Additional render methods go here
// Please reference existing Renderer classes and open a GitHub issue if you need help
}
Blog post with an older example: http://blog.quicktype.io/customizing-quicktype/