We’re thrilled to announce our new release of Retyped and that we have added support for 1200+ new binding libraries. This brings the total count of binding libraries that can be used in Bridge.NET projects to 3600+.

“Retyped now supports using 3600+ JavaScript libraries in C# projects when paired with Bridge.NET.”

Quick Facts About Retyped

1500+ commits to the main Retyped source code repository Retyped solution includes 14 projects and 25000 LOC (VS Code Metrics) 2000+ unit tests cover parsing and translation logic Retyped reads NPM, DefinitelyTyped, and the original repositories to collect TypeScript declaration files for each library Retyped contains 25000 d.ts files belonging to 4000+ libraries Generated C# solutions require 100 GB of disk space Full recompilation takes 2 hours (4 threads on Core i7) 3600+ Retyped packages are now available on NuGet Total downloads of all Retyped packages now exceeds 1.0 million Most popular packages are Retyped.jquery and Retyped.node

Evolving Retyped is so exciting for our team and we continue to incrementally improve Retyped every day.

What’s New In Retyped 1.5

This release includes fixes and enhancements for approximately 100 issues and the notable new features are outlined below.

Support For NPM

Since it’s inception, Retyped has only been using DefinitelyTyped as the sole source of declaration files. Retyped new properly manages hundreds of packages published only to NPM or individual GitHub repos.

In addition to reading the original .d.ts files, Retyped also tracks metadata for each library including the author(s), version number, and description. See decimal.js for an example.

Many libraries are no longer publishing their official .d.ts files to DefinitelyTyped, so to ensure only the most up to date library releases are included, Retyped will find the official source location and read from there.

Virtual Members

All class members (except ObjectLiteral members) are now declared with virtual modifier which enables a cleaner technique for overriding. Just compare the following code samples.

Old Syntax

https://deck.net/70b444440f3bdd37ee238ea64c29f915

public class MyConsole : SpecialConsole

{

[Name("Print")] // <-- overrides the external base member

public void Print(string msg)

{

Console.WriteLine(msg);

}

} [External]

public class SpecialConsole

{

public extern void Print(string msg);

}

New Syntax

https://deck.net/fb15de62219f27a9379f07c84d143214

public class MyConsole : SpecialConsole

{

public override void Print(string msg)

{

Console.WriteLine(msg);

}

} [External]

public class SpecialConsole

{

public virtual extern void Print(string msg);

}

Expressions In Enum Declarations

Retyped can now emit proper C# for libraries declaring enum members with the use of expressions.

enum Permission

{

Nobody = 0,

Owner = 1,

Officer = 2,

Member = 4,

Moderator = 8,

AllMembers = Owner | Officer | Member | Moderator

}

Delegate Types And Inheriting

There are two ways of declaring a delegate type in TypeScript:

TypeScript Playground

type ToStringDelegate1 = (n: number) => string; interface ToStringDelegate2 {

(n: number): string;

}

Previously Retyped created a delegate declaration for ToStringDelegate1 and an interface declaration for ToStringDelegate2 . Now both types will be emitted identically:

public delegate string ToStringDelegate1(double n); public delegate string ToStringDelegate2(double n);

An interface declaration won’t be collapsed to a plain delegate type, if it contains additional members, or if it derives from another delegate.

In this case, some helping members might be generated (if possible): a constructor accepting the argument of delegate type and a set of implicit operators — all these will help with initializing and casting.

Fixed Constructor Types

Constructor types remind function types with the main difference, they assume the new keyword will be used.

In order to guarantee that, Retyped generates a class containing a constructor allowing to initialize the constructor type using LINQ Expression. The expression points to a specific constructor of some type. Another useful member is Invoke method which calls the provided constructor and creates an instance of the type.

TypeScript

class A { /* .. */ } let aCtorType: new () => A;

aCtorType = A; let a = new aCtorType();

C#

https://deck.net/5fbcef09355da563d9b754561179d657

public class Program

{

public static void Main()

{

ACtorFn aCtorType;

aCtorType = new ACtorFn(() => new A()); var a = aCtorType.Invoke();

}

}

Import/Export Default Statements

Previously Retyped had some gaps in processing export default statements.

Now such statements are fully supported, both in parsing and type resolution logic. So given the following TypeScript code:

declare module "test" {

namespace NS {

class A {

}

}

export default NS.A;

}

... the following C# will be generated:

[Retyped.Scope]

[Bridge.GlobalMethods]

[Retyped.ExportedAs("NS.A", IsExportDefault = true)]

[Bridge.Module(Bridge.ModuleType.UMD, false, Name = "test")]

public static class test

{

[Retyped.Scope]

public static class NS

{

[Bridge.Name("default")]

[Retyped.ExportedAs("test.NS.A")]

public class A : Retyped.IObject

{

}

}

}

Ambient Modules

There were several enhancements devoted to ambient modules. These include name collision prevention, augmentation, type resolution, and supporting various techniques for importing and exporting, including aliases. For example, in TypeScript one entity could be imported using several different statement styles.

import * as lib from ".."

let a: lib.A; import { A } from ".."

let a: A; import A from ".."

let a: A; import { A as B } from ".."

let a: B;

All the above now work both in regular and ambient modules.

Generic Constraints

It’s the most important and at the same time difficult topic to address. We had been trying to fix issues related to generic constraints, but they kept returning back as more and more complicated scenarios.

We came to the conclusion that TypeScript constraints just can’t be handled with the C# constraints system. This had us thinking about implementing our own mechanism for constraining types. We proposed implementing a new [Where] attribute allowing application of flexible constraint rules. For example, constraining Union types or Type Aliases.

More work is being done on the [Where] attribute implementation and we would appreciate your feedback. See Bridge Issue #3452 for more details.

Type Resolution Testing

As mentioned above, we have more than 2000 unit tests helping us to verify the quality and consistency of the generated C# code for Retyped across all 3600+ supported libraries. Managing such a large number of projects with the related suite of unit tests is not a simple task and requires a high level of automation.

This topic deserves a dedicated blog post, but as a quick insight for now, we have integration tests covering the full Retyped lifecycle including loading libs -> parsing -> emitting C# -> generating solutions -> resolving all dependencies -> full recompilation -> generating NuGet packages -> publishing to NuGet .

Retyped Demos

The Retyped Demos website currently contains 15 demo projects and more will be added soon. The source code for all Demos are available on GitHub.

Creating many of the Retyped Demos involved a simple port of the original sample from JavaScript into C#. In most cases, we were able to simply copy/paste JavaScript code directly into the C# project, then perform a few trivial adjustments, such as transforming JavaScript function signatures into C# method declarations.

Thanks to the Retyped naming convention, most of JavaScript API usage does not require adjustments, such as re-casing from camelCase to PascalCase. That basic feature of Retyped saves an enormous amount of time, reduces points of failure, and ensures compatibility with the original library.

We’re trying to create demo projects with C# source code that closely preserves the original authors intent, including both functionality and syntax style.

When using Retyped and Bridge it’s amazing how boundaries get erased between different technologies and languages.

Retyped Versioning

The Retyped package versioning schema has raised a few questions, so let’s outline some of our initial requirements and final approach.

Requirements:

Retyped packages could be treated like Bridge.NET bindings that makes them dependent on Bridge.Core which provides information about required Bridge version. We needed to be able to track what version of Retyped compiler was used to generate a package. Declaration files are tightly connected with the TypeScript version they built against. This is another piece of information that must be identifiable. Each library has its own version, so it should also be reflected by the Retyped package. The build process is fully automated, so having an indication of the compiling date timestamp was required.

Approach:

A base package was created and added as a dependency to each Retyped package. The package was called Retyped.Core , it contains Retyped-specific types such as attributes. Retyped.Core package depends on Bridge.Core — together they provide information about Retyped and Bridge.NET compiler versions accordingly.

, it contains Retyped-specific types such as attributes. package depends on — together they provide information about Retyped and Bridge.NET compiler versions accordingly. Retyped packages like Retyped.es5 or Retyped.dom are built based on TypeScript base libraries, so they could represent TypeScript version.

or are built based on TypeScript base libraries, so they could represent TypeScript version. A Retyped package created for a library gets the version of that library.

All packages mentioned above get patch version representing a number of days passed since January 1, 2000 (calculator).

Lets take the Retyped.node package and some of its dependencies as an example:

Retyped.node 9.6.6685 = NodeJS 9.6

= NodeJS 9.6 Retyped.dom 2.8.6685 = TypeScript 2.8

= TypeScript 2.8 Retyped.Core 1.5.6685 = Retyped 1.5

= Retyped 1.5 Bridge.Core 17.0.0 = Bridge 17.0

= Bridge 17.0 *.6685 = Release date was 6685 days after 2000–01–01 = 2018–04–20

Hope that information helps you better navigate among Retyped package versions and releases.

Retyped Roadmap

This release is a big milestone for Retyped. It’s been a while since we pushed such a massive update syncing with the latest declarations.

There is still the road ahead though. Plans are in place to implement features such as nightly incremental builds and self-contained packages with all required JavaScript files for each package embedded within.

Retyped and Bridge Premium

Did you know Bridge.NET is community supported free open-source software? We fund development of Bridge and Retyped by providing value-added Premium Plugins and expedited Premium Support services. Please check out the Bridge Pro and Enterprise Premium options.

Thanks for your interest in Retyped and Bridge.NET!