Converting a Javascript Project to Typescript for Beginners
January 4, 2018
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:
- Rename the file from .js to .ts
- 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.
- Change all
var
tolet
- it's typescript version of the keyword to define a variable and our linter/internal style preferslet
- Change
var NurseAlarmReviewsVM = function (data) {
toclass 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 callingnew NurseAlarmReviewsVM(data)
- Add a constructor to the class -
- 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)
- 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 dovar self = this;
, it is smart enough to treatthis
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.
- Remove
var self = this
and replace allself.
withthis.
. Trust typescript to figure out what you mean.
In projects with a Typescript linter:
- 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.