Writing Models in TypeScript

One of the suggested advantages of JavaScript is it’s flexibility in type system. A variable can be a number, string, null, undefined, object or array at various points. I actually find that one of the languages weaknesses. It suggests sloppy programming. A number of other people have suggested the same thing, which is why languages like TypeScript and Dart have been invented – to give type safety in an arena where type safety is anything but guaranteed.

Most mobile applications these days have a server component and a client component. The client component runs on the mobile device or in the browser and the server component runs in the cloud – on an Azure App Service Web App, for example. This brings a problem with it. How do you keep the models in sync? If one side of the code is in JavaScript and one is in dot-NET, then it is highly likely that the models will be defined in separate places.

To get around that, I define the interfaces in the same location and put a comment reference to remind me to keep them in sync. There isn’t really a good way to provide a single language that then does code generation right now. However, by simplifying the language constructs you do use, you can also simplify the process of maintenance. In general, I am coding in Visual Studio 2015, so I have a “Shared” project in my solution that contains both artifacts.

Let’s say I have the following model – it’s fairly simple and it’s from my Grumpy Wizards application:

using System.Collections.Generic;

namespace Shared.Models
    // If you update this, then also update ../Interfaces/IGWUser.ts
    public class GWUser
        public int Id { get; set; }
        public string Name { get; set; }

        public string FacebookId { get; set; }
        public string TwitterId { get; set; }
        public string MicrosoftId { get; set; }
        public string GoogleId { get; set; }

        public ICollection<GWCharacter> Characters { get; set; }

This is a fairly straight forward model. I’ve got the GWCharacter defined in much the same way in another file. To generate this, I created a Shared project with the Visual C# -> Web -> Class Library (Package) template. This provides for both client-side and server-side item templates and allows me to include both C# and TypeScript files in the same project. I’ve placed the C# files in a directory called Models, so my namespace is Shared.Models. I normally alter the namespace to be something like Grumpy.Wizards.Shared in the project properties before creating the files to give them a better namespace.

Now for the TypeScript file. This is stored in the same project but in a different directory – Interfaces. In this case, I’m going to create an IGWUser interface to represent the model:

import IGWCharacter = require('./IGWCharacter');

module Grumpy.Wizards.Shared {

    export interface CharacterList {
        [index: number]: IGWCharacter;

    // If you update this, then also update ../Models/GWUser.cs
    export interface IGWUser {
        id: number;
        name: string;
        facebookId?: string;
        twitterId?: string;
        microsoftId?: string;
        googleId?: string;
        characters: CharacterList;


There are many similarities between the two models, but they aren’t quite the same. The most obvious difference is that I have to define a character list interface in the TypeScript definition. I suppose I could use an Array generic (Array<IGWCharacter>), but this format makes it much more apparent. Also, there is the ? after the variable names in the TypeScript version. This designates an optional property. To do this in the C# world, I need to turn to Data Annotations. This is especially true when the model is backed by a database of some description. In this case, you will be using Data Annotations to describe the SQL Model in a Code-First Entity Framework environment. In that case, I highly recommend watching Julie Lerman on Pluralsight and she pretty much wrote the book on Entity Framework. One blog post by a recreational programmer will not do the subject justice.

So, how do I use these models? Now I can use the backend and front end of my choice and get truly cross-platform development. I avoid Objective-C, Swift and Java.Android – those are platform specific languages and I won’t get the coverage I want. However, I can choose C# as a development language and write the backend API in C# and deploy to Azure, then write the front end in Xamarin Forms and get an iOS and Android mobile app out of it. If I prefer Cordova/PhoneGap, then I can write in TypeScript and transpile down to JavaScript – I still get to choose a backend in NodeJS or C#. There are basically no restrictions.