clr2ts 0.6.1

dotnet tool install --global clr2ts --version 0.6.1                
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest # if you are setting up this repo
dotnet tool install --local clr2ts --version 0.6.1                
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=clr2ts&version=0.6.1                
nuke :add-package clr2ts --version 0.6.1                

clr2ts

Build status GitHub Nuget (with prereleases)

Transpiler that takes CLR assemblies and outputs corresponding typescript definitions.

Demo Gif

Installation

Get clr2ts by installing it as a dotnet tool from nuget.org.

dotnet tool install -g clr2ts

More information about installing dotnet tools can be found here.

Usage

Run clr2ts by calling the dotnet tool with the configuration file you would like to use.

clr2ts your.config.json

If you call clr2ts without specifying a configuration file, it will automatically look for one in the current working directory and its parent directories using the search pattern *clr2ts.json. If you use relative paths in your configuration, they are always relative to the configuration file.

Configuration

The following example shows a complete configuration file that demonstrates simple settings. More complex scenarios are described in detail below.

{
    "input": {
        /* Required: At least one assembly that should be translated. */
        "assemblyFiles": [
            "./Path/To/Your/Assembly.dll"
        ]
    },
    "logging": {
        /* Write log messages to the console. */
        "console": true,
        /* Write log messages to a file. */
        "file": "./clr2ts.log"
    },
    "transpilation": {
        /* Specify if property names should be converted to camelCase (TypeScript convention). */
        "camelCase": true,

        /* Specify if base class hierarchies should be removed and instead all properties repeated in the subtype.*/
        "flattenBaseTypes": true
    },
    "output": {
        /* Write all TypeScript types into a single file.*/
        "bundledFile": "./Path/To/Your/File.ts",

        /* Write TypeScript types to individual files in a directory. */
        "files": {
            "directory": "./Path/To/Your/TypeScriptCodeBase/directory",

            /* Specify if a directory structure should be created following the namespaces of the assembly (otherwise all types are put into the directory). */
            "mimicNamespacesWithSubdirectories": false
        }
    }
}

Type filters

In most cases, clr2ts should not translate all types in the source assembly, but rather a specific subset. You can define type filters to control which types should be translated. clr2ts will still translate dependencies of the matching types, even if they do not match the filter criteria. If you do not want to create translations of specific dependencies you can use custom type maps (see below) to map those to the any type, for example.

"input": {
    /* Define multiple filters for OR-semantics. */
    "typeFilters": [
        /* Multiple values in a single filter for AND-semantics. */
        {
            /* Filters types that have all of the specified attributes applied to them. The "Attribute"-suffix can be omitted. */
            "hasAttribute": ["AttributeName"],

            /* Filters types that are a subtype of all of the specified types. */
            "subTypeOf": ["BaseType", "SomeInterface"],

            /* Filters types that are defined in the specified namespace (StartsWith-semantic). */
            "namespace": "Namespace.SubNamespace"
        }
    ]
}

Custom Type Maps

Custom type maps are used to specify types that should be mapped to existing TypeScript definitions and not be translated by clr2ts.

"transpilation": {
    "customTypeMaps": [
        /* Importing a type definition from the surrounding code base. */
        {
            "type": "Namespace.TypeName",
            "name": "CustomType",
            "source": "../../CustomType"
        },
        /* Importing a type definition from a library. */
        {
            "type": "Namespace.TypeName",
            "name": "LibraryComponent",
            "source": "@lib/library"
        },
        /* Referencing a type that does not need to be imported, like "any". */
        {
            "type": "System.Type",
            "name": "any"
        }
    ]
},

Decorators

You can configure clr2ts to apply decorators to the translated TypeScript definitions. Decorators can be applied to classes and properties. You can specify the parameters that should be passed to the decorator in the format of simple template strings, which can include information from the current context (providing information about the current type or property, its attributes, the assembly, and more).

"transpilation": {
    "classDecorators": [
        {
            /* Condition specifying where the decorator should be applied, see type filters. */
            "if": {
                "namespace": "Clr2Ts.EndToEnd.Targets.SubTyping"
            },
            /* Name of the decorator that should be applied. */
            "decorator": "typeName",
            /* Parameters that should be passed to the decorator. */
            "parameters": ["{Type.FullName} + ', ' + {AssemblyName.Name}"],
            /* Optional import of the decorator definition. */
            "import": "../../typeName.decorator"
        }
    ],
    "propertyDecorators": [
        {
            "if": {
                /* Type allows you to specify a full type filter (see above) for the property's declaring type. */
                "type": { "namespace": "Clr2Ts.EndToEnd.Targets.SubTyping" }
            },
            "decorator": "propertyName",
            "parameters": ["{Type.FullName} + '.' + {Property.Name}"],
            "import": "../../propertyName.decorator"
        }
    ]
},

The example above demonstrates that decorators do not have to match attributes in the source assembly, but can be applied by arbitrary conditions (type filter mechanism). This still allows you to map decorators from attributes if you want to:

/* Decorator configuration that maps the DisplayAttribute from the source assembly to the display decorator. */
{
    "if": { "hasAttribute": [ "Display" ] },
    "decorator": "display",
    "parameters": [ "{Attributes.Display.Name}" ],
    "import": "@decorators/display"
}

Enum attribute maps

As of now, TypeScript does not support decorators for enum members. If you need information from attributes applied to enums in the source assembly, clr2ts supports a workaround in the form of simple maps stored in the TypeScript enum itself. For example, the following configuration instructs clr2ts to generate a map for the DisplayAttribute.Name property like shown below:

"transpilation": {
    "enumAttributeMaps": {
        "_displayNames": "{Attributes.DisplayAttribute.Name}",
        "_displayDescriptions": "{Attributes.DisplayAttribute.Description}"
    }
},

Enum definition (C# example):

public enum ExampleEnum
{
    [Display(Name = "DisplayName1")]
    Value1,

    [Display(Name = "DisplayName2")]
    Value2,

    [Display(Name = "DisplayName3")]
    Value3
}

TypeScript translation:

export enum ExampleEnum {
	Value1 = 0,
	Value2 = 1,
	Value3 = 2
}

(<any>ExampleEnum)._displayNames = {
	[ExampleEnum.Value1]: "DisplayName1",
	[ExampleEnum.Value2]: "DisplayName2",
	[ExampleEnum.Value3]: "DisplayName3"
};

Reusable configuration files

You can define tokens that should be replaced in a configuration file to reuse it for different purposes or build configurations.

{
  "input": {
    "assemblyFiles": [
      /* $OutDir$ will be used as a custom token */
      "$OutDir$/Assembly.dll"
    ]
  }
}

The actual values to put into the configuration files are defined by command line arguments when calling clr2ts:

clr2ts your.config.json $OutDir$=MyDirectory

You are free to choose the name of your tokens to avoid conflicts with any special characters in your scenario, but the name must not contain =.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last updated
0.6.1 1,151 5/2/2024
0.6.0 5,939 2/19/2024
0.5.1 223 1/21/2024
0.5.0 172 1/21/2024
0.4.2 2,418 7/24/2023
0.4.1 3,532 6/20/2023
0.4.0 4,727 3/1/2022
0.3.3 527 1/19/2022
0.3.2 478 1/18/2022
0.3.1 704 2/17/2021
0.3.0 683 10/14/2020
0.2.4 425 10/9/2020
0.2.3 733 5/19/2020
0.2.2 583 5/8/2020
0.2.1 622 2/25/2020
0.2.0 564 2/24/2020
0.1.9 552 12/13/2019
0.1.8 515 12/4/2019
0.1.7 623 8/25/2019
0.1.6 675 5/19/2019
0.1.5 608 5/1/2019
0.1.4 590 4/27/2019
0.1.3 683 4/20/2019
0.1.2 630 4/19/2019
0.1.0 612 4/16/2019

Support DateOnly and TimeOnly out of the box (can be overridden via custom type maps).