For those who do not know Typewriter:
NTypewriter is files generator from text templates populated with meta-data about your C# code. It is like a specialized and more convenient T4 design-time template.
With NTypewriter you can:
- auto-generate documentation for your C# code
- create a typed TypeScript API client for your ASP.net web API
For those who know Typewriter:
NTypewriter is a younger and more immature brother of beloved Typewriter. They share the same ideas, but with a completely different implementation. NTypwriter uses Scriban as a template engine, thus templates files are completely not interchangeable. While code model api is about 95% compatible between them, there are some differences. NTypewriter code model is 100% pure, without any amenities that helps generate TS files. All things that help generate TypeScript from ASP.NET are located in built-in functions: Action, Type.
Oh, did I forget to mention that NTypewriter also solves most of the awaited issues of the Typewriter that were promised for 2.0 version:
- support for attribute properties/values, statics, indexers, default parameters, nullable, records, constructors
- output multiple types to single file
- include types in CodeModel from referenced assemblies/nugets
- save generated file only when file content has changed
- sharable custom functions
- full control over whitespaces
- CLI is possible
- built-in support for getting all types used in class declaration (Type.AllReferencedTypes)
- you can debug custom functions
-
Getting started
-
Documentation
- Language
- Code model
- Built-in functions
- Name vs BareName vs FullName
- Custom Functions
- Configuration
- Visual Studio Configuration
Typewriter | NTypewriter | |
---|---|---|
Template file extension | *.tst | *.nt |
Syntax | typewriter syntax | scriban scripting language |
Lambda filters | present | not available |
Can be used from CLI | no | yes |
Full control over whitespaces | nope | yup |
Mapping | one input always produces one output file | you can generate as many files as you want |
Live preview | no | yes |
Code model | ||
Unit of work | file | there is no concept of a file in NTypewriter, you work on compiled symbols |
Access modifiers | code model contains only public types | code model contains all types |
Partial classes | treated as separate units | all parts of the class are treated as a whole unit |
Automation | ||
Auto-render template on save | yes (opt-out is possible) | yes (opt-in is possible) |
Auto-render when C# file changes | yes (opt-out is possible) | no |
Auto-render on build | no | yes (opt-in is possible) |
Custom functions | ||
Placement | inside template file (.tst) | in seperate file (*.nt.cs) |
Can be shared | separate for every template | shared between templates inside a project |
Can be debug | no | yes |
Can be unit tested | no | yes |
VS Integration | ||
Supported versions of Visual Studio | 2015, 2017, 2019 | 2019 (min ver 16.11.x), 2022 |
Add generated files to VS project | yes (opt-out is possible) | yes (opt-out is possible) |
Sync deleted or renamed C# types with generated files | there is a part of the code that should do that but it does not work anymore | yes |
Typewriter template:
module App { $Classes(*Model)[
export class $Name { $Properties[
public $name: $Type;]
}]
}
equivalent NTypewriter template will be :
{{- for class in data.Classes | Symbols.WhereNameEndsWith "Model"
capture output -}}
module App {
export class {{ class.Name }} {
{{- for property in class.Properties | Symbols.ThatArePublic }}
public {{ property.Name | String.ToCamelCase }}: {{ property.Type | Type.ToTypeScriptType }};
{{- end }}
}
}
{{- end
filePath = class.BareName | String.Append ".ts"
Save output filePath
end }}
yes, it is more verbose, but maintaining it over time will be much easier. Both templates generate exactly the same output:
module App {
export class CustomerModel {
public id: number;
public name: string;
public orders: OrderModel[];
}
}
All examples available on Typewriter page are also available in NTypewriter version:
example | NTypewriter | Typewriter |
---|---|---|
CreateYourFirstTemplate | CreateYourFirstTemplate.nt | CreateYourFirstTemplate.tst |
Extensions | Extensions.nt | Extensions.tst |
ModelInterfaces | ModelInterfaces.nt | ModelInterfaces.tst |
KnockoutModels | KnockoutModels.nt | KnockoutModels.tst |
AngularWebAPIService | AngularWebAPIService.nt | AngularWebAPIService.tst |
- Install NTypewriter editor for Visual Studio
- Add template file with *.nt extension to your project
- You gain access to code model from your template by special global variable
data
. So let us iterate over every class defined in solution, and write its name to output.
{{ for class in data.Classes
class.FullName | String.Append "\r\n"
end }}
- Now it is time to decide what part of our template will be saved to a file. We do that by using capture statement
capture variableName; end
. For this example we want to generate one file with list of all classes defined in solution, thus we should use capture statement outside of the for loop.
{{ capture output
for class in data.Classes
class.FullName | String.Append "\r\n"
end
end}}
{{ capture output
for class in data.Classes
class.FullName | String.Append "\r\n"
end
end
Save output "index.txt"
}}
- If something goes wrong you can look at NTypewriter output. NTypewriter is very chatty about what is doing at the moment. Most of the errors also will appear on the VS Error List.
NTypewriter does not have own a lexer/parser as Typewriter has, and uses Scriban instead to do heavy work. Scriban works very well with fully correct templates, but with incomplete templates during edition not so much. It is the source of the most glitches in the Editor. Scriban language is also typeless, thus doing code completion is challenging.