4

TypeWalker – keeps your c# DTOs in sync with TypeScript

 3 years ago
source link: https://stevedrivendevelopment.com/2015/06/17/typewalker-keeps-your-c-dtos-in-sync-with-typescript/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

TypeWalker

(Now available on github and nuget)

With TypeScript, Microsoft introduced a nice, strongly-typed way to develop a variant of JavaScript. It’s been written to be nicely agnostic to other languages — it’ll run for node.js server-side apps just as easily as integrating with your C# MVC projects. However, for complex C# apps, it’s really useful to have your TypeScript and your C# in lockstep.

For instance, let’s say you have an MVC controller returning a list of person records;

[HttpGet]
public ActionResult GetPeople() 
{
    PersonDto[] people = personRepo.GetAll(l);
    return Json(people, JsonRequestBehavior.AllowGet);
}

So far so good. You probably consume it in JavaScript like so;

$.getJson('/People/GetPeople', function(data) {
    // data will look like; 
    //    [
    //        { "firstName": "alice", "id": 1 },
    //        { "firstName": "bob", "id": 2 },
    //    ]
});

But in TypeScript we want to strongly type it, so we want to do something more like;

$.getJson('/People/GetPeople', function(data: PersonDto[]) {
    ...
});

where you can now see the PersonDto[] type annotation. This gives you strong typing throughout the function. So somehow I need to write a typescript interface;

interface PersonDto {
    firstName: string;
    id: number;
}

This is fine, but you’ve already got a PersonDto.cs file somewhere in your C# file, and there is no benefit in you coding both, at the risk of violating DRY, and at the risk of things going out-of-date over time.

Also, I like Knockout.js, and especially the mapping plugin, which converts POJOs into bindable objects. But these have different interfaces from the original object — a name property becomes aname() getter function and a name(value) setter function. This is fairly predicable, so to get TypeScript support you would need to add a third description of the class;

module KnockoutVersion {
    interface PersonDto {
        firstName(): string;
        firstName(value:string): void;
        id(): number;
        id(value:number): void;
    }
}

So that’s three descriptions of the same basic type. Urgh!

TypeWalker is a project which generates your TypeScript definitions from your C# types. This spares you the effort of keeping things in sync, and offers some stronger guarantees that your JavaScript will be less likely to contain the mistakes that creep in when people add or remove properties to classes or otherwise change the signature of a type.

At the moment it operates using the command line. You should be able to use it now by calling it manually. I am currently working at building it as a NuGet package which will extend a web application project and automatically build your TypeScript types at build time.

Command Line Operation

TypeWalker 
    /configFile=c:\src\mysite\AssembliesToOutput.txt 
    /language=KnockoutMapping 
    /knockoutPrefix=KOGen 
    /outputFile=c:\src\mysite\scripts\typings\mysite.d.ts

configFile is a text file containing lines formatted like so;

MyClassLibrary::My.Namespace.To.Export

So, pairs of assembly names (without .dll extension) and a namespace within that class library to export.

language is currently one of KnockoutMapping or TypeScript. You can call the app twice if you want both. Over time, I’ll make the languages pluggable, but right now they’re fixed.

knockoutPrefix is a namespace prefix for Knockout-generated files. This lets you generateMyModule.Person for your POJOs and KO.MyModule.Person for your knockout versions.

outputFile is just the file where the file should be written. Usually a .d.ts TypeScript definition file.

NuGet/MSBuild Integration

There’s rudimentary NuGet support;

Install-Package TypeWalker -Pre

Run this in your web app. This will install the binary and modify the .csproj file with the appropriate MSBuild targets. You now need to save the project, close and re-open the solution.

Next, you need to write a file containing the assembly names and namespaces to export — see above under the configFile documentation. Add this file to the project, then edit the properties of the file. Change the Build Action to GenerateTypeScriptResources.

Save, possibly close and re-open again, then start building. It’ll generate your output, switching the extension to .d.ts. For example;

Scripts/TypeWalker.txt
Scripts/TypeWalker.d.ts

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK