Build-Time Type Generation
Automatically generate F# types from JSON files at build time using Fabulous.AST.Build.
This extension provides an MSBuild task that watches JSON files and generates F# record types during compilation.
Installation
|
💡 Tip: For programmatic control over generation, see the JSON Extension tutorial.
Quick Start
1. Add a JSON schema file
Create schemas/user.json:
|
2. Configure your project
Add to your .fsproj:
|
3. Build
|
This generates Generated/user.Generated.fs:
type Root = {
id: int
name: string
email: string
isActive: bool
}
Configuration Options
Custom Root Type Name
Override the default Root type name:
|
Add a Module
Wrap types in a file-level module:
|
Generates:
module MyApp.Models
type User = { id: int; name: string; email: string; isActive: bool }
Note: Each file must have a unique module name since file-level modules cannot share the same fully-qualified name.
Custom Output Directory
Change the output location:
|
Custom Output Filename
Override the default {name}.Generated.fs pattern:
|
Multiple Files
Individual Configuration
|
Glob Patterns
Process all JSON files in a directory:
|
Type Inference Examples
Nested Objects
Input (company.json):
|
Output:
type Address = { street: string; city: string }
type Company = { name: string; address: Address }
Arrays
Input (users.json):
|
Output:
type UsersItem = { id: int; name: string }
type Users = UsersItem list
Optional Fields
Fields missing in some array objects become option types:
Input:
|
Output:
type RootItem = { id: int; name: string; nickname: string option }
type Root = RootItem list
Type Inference Rules
JSON Value |
F# Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Record type |
Special Field Name Handling
Leading Digits
Fields starting with digits are prefixed with _:
|
Generates: _2faEnabled: bool
Reserved Keywords
F# keywords are escaped with double backticks:
|
Generates: ``type``: string
Configuration Reference
Project Properties
|| Property | Default | Description |
||----------|---------|-------------|
|| FabulousAstJsonOutputDir | Generated/ | Output directory |
|| EnableFabulousAstJsonGeneration | true | Enable/disable generation (set to false to skip) |
Note:
EnableFabulousAstJsonGenerationdefaults totrue, so you only need to set it explicitly if you want to disable generation.
Item Metadata
|| Metadata | Default | Description |
||----------|---------|-------------|
|| RootName | Root | Root type name |
|| ModuleName | (empty) | File-level module name (e.g., MyApp.Models) |
|| OutputFileName | {InputName}.Generated.fs | Output filename |
Incremental Builds
The task uses content hashing for efficient builds:
- Files regenerate only when JSON content changes
- Configuration changes trigger regeneration
- Generated files include hash comments for verification
IDE Integration
Generated files are created during the build process. Due to how MSBuild evaluates projects, your IDE may not immediately recognize newly generated files.
Recommended: Explicit File Listing
For the best IDE experience, explicitly list generated files in your project:
|
This way, the IDE knows about the file path upfront and will recognize it once generated.
Using Glob Patterns
If you prefer glob patterns:
|
Note that after the first build (or after clean), you may need to reload the project in your IDE for it to pick up the new files.
Tips
- Keep generated files in source control - This avoids the "first build" issue and ensures CI builds work immediately.
- Don't delete generated files - The incremental build only regenerates when JSON content or configuration changes.
Troubleshooting
IDE Not Seeing Generated Files
If your IDE doesn't recognize the generated types after building:
1. Try reloading/refreshing the project
2. Switch from glob patterns to explicit file listing
3. Ensure the generated file exists in the Generated/ folder
File Not Updating
|
Build Fails After Clean
This is expected on the first build after dotnet clean when using glob patterns. The generated file doesn't exist when MSBuild evaluates <Compile Include="Generated/*.fs" />. Simply run dotnet build again.
Disable Generation
Via project property:
|
Via command line:
|
Next Steps
- Learn about programmatic generation with Fabulous.AST.Json
- Explore the Fabulous.AST DSL for more code generation options
val int: value: 'T -> int (requires member op_Explicit)
--------------------
type int = int32
--------------------
type int<'Measure> = int
val string: value: 'T -> string
--------------------
type string = System.String
Fabulous.AST