I couldn't find a Typescript conversion guide for a new developer on our team who was not familiar with Typescript, so I made him one. Most guides to getting started with Typescript out there assume the reader is starting a project that doesn't have the build set up, so they include cruft at the beginning that you don't need to understand yet if you're working with a project that already has the compiler set up--especially in Visual Studio where you don't have to run any tsc commands ever.

This guide assumes that you're using Knockout for ViewModel bindings, though you can be using anything else too and the same basic principles will apply. It also assumes you're using Visual Studio or another IDE where Typescript compiling happens automatically when you build your project.

Basic Types

To start off, here are some basic Typescript types that we use in our project:

boolean, number, string,
boolean[] = array of booleans

KnockoutObservable<number> = ko.observable(number);

KnockoutObservableArray<string> = ko.observableArray(arrayOfStrings);

JQuery = $('selector')

You can also have class, interface, enum, which work the way you'd expect.

To convert a file you wrote in javascript to Typescript, follow these steps:

  1. Rename the file from .js to .ts
  2. Remove the .js version from your git working tree if it's been checked in already- we only check in the .ts files, and the .js files are generated by the compiler.
  3. Change all var to let - it's typescript version of the keyword to define a variable and our linter/internal style prefers let
  4. Change var NurseAlarmReviewsVM = function (data) { to class NurseAlarmReviewsVM {
    • Add a constructor to the class - constructor(data) { ... }
    • Create a new instance of the VM in the view to pass to Knockout ko.applyBindings() by calling new NurseAlarmReviewsVM(data)
  5. What do you expect data to be in the constructor? Create an interface for it and then decorate the data parameter with the type by making it look like this: constructor(data: IData)
  6. Wherever you define an anonymous function, switch it to the arrow syntax. This syntax is nice because it captures this - in typescript you don't have to basically ever do var self = this;, it is smart enough to treat this like you'd expect it to work in a sane language. (this in a class refers to the instance of the class)
// Switch this: 
function (x) { 
  x = x + 1;
  return "Did stuff";
}

// to this new "arrow syntax" style of defining a function:
(x: number): string => {
  x = x + 1;
  return "Did stuff";
}
  • What's that xType doing there? That's a type definition. It will prevent you from doing silly stuff later when you go to use that variable, so try to add them where you can.
  • What about the : string after the first parameter? That's defining the return type. It's optional, but really nice to have.
  1. Remove var self = this and replace all self. with this.. Trust typescript to figure out what you mean.

In projects with a Typescript linter:

  1. Fix any other things the Typescript linter (compile-time syntax/style checker) tells you to fix. You might see "no magic numbers". Make your magic numbers named constants or at least a named variable and then use that. Exceptions are for 1, 0 and possibly -1.