Software Engineering Musings

TypeScript for .NET (and maybe Java) Engineers

July 12, 2020

What follows is, mostly, geared towards Software Engineers with experience in .NET, Java, or something like it, who are either wanting to, or forced to, jump into TypeScript code or projects.

That said, I do hope it’ll be of use to other engineers looking (or needing) to jump into in TypeScript.

My Context

To cut a long story short, most projects I created, historically, consisted of a JavaScript front-end and .NET back-end.

And I loved it.

I had my yin and yang, my safe and comfortable .NET utopia, and my wild-west JavaScript front end.

But ultimately, I saw the writing on the wall, that TypeScript adoption was picking up at an ungodly pace, and to stay competitive and on the curve, I would have to learn TypeScript.

Are you a JavaScript Developer?

If you are, or otherwise consider yourself to be, a JS developer, then the reality is that you’re already thinking in types. You should learn TypeScript, you won’t regret it — I promise — and it will do wonders for your ability and career.

Who created TypeScript and how is it updated?

TypeScript was created by Microsoft, yes, however it is and has always been open source. As for updating, that’s where it gets, in my opinion, very cool.

Then there’s the ECMA International standards organisation, that oversee a wide range of standards, one of which, ECMA-262, oversees EcmaScript, which for the sake of this, you can consider JavaScript.

Tehcnical Comittee 39 (TC39) is the TC that oversees this. Such that when anyone wants to add a feature to EcmaScript, they need to submit a proposal to TC39.

There are many stages a proposal has to go through, but stage 3 is when it gets serious. At stage 3, it’s very unlikely that it wont make it into the EcmaScript spec. This is the point that a given feature will be, generally, implemented in TypeScript, allowing you to use it (or do so via Babel if that’s your jam or project requirement).

If you’re that way inclined, as I am, you can keep up to date with proposals on the tc39/proposals repo on Github.

Also, notably, one of the primary language designers behind TypeScript is Anders Hejlsberg, who is also behind Turbo Pascal, Delphi, and C# — you are in safe hands.

On to TypeScript for the .NET/Java/etc crowd

The TypeScript TL:DR;

It’s a superset of JavaScript, so you write TypeScript, and one way or another it’ll transpile to JavaScript. Further, it is valid to write JavaScript code in TypeScript.

But in essence, it’s statically type-checked JavaScript.

Modeling Data

There are few ways to go about this. The first, and the one that I use most often, would be the interface. Consider the following;

interface User {
  userName: string;
  email: string;
  firstName: string;
  lastName: string;
}

const user:User = {
  userName: 'someuser',
  email: 'user@email.com',
  firstName: 'fakeFirstName'
  lastName: 'fakeLastName'
};

Another way is to use a type, such as this

const user = {
  userName: 'someuser',
  email: 'user@email.com',
  firstName: 'fakeFirstName'
  lastName: 'fakeLastName'
};

type User = typeof user;

Either is fine, though I prefer the first approach, and it’s mostly just a preference, though seems to be fairly conventional.

A good use case for this is when you’re modeling data to be posted to, or received from some kind of API.

Classes

It’s completely acceptable to use classes in TypeScript, but my suggestion is that you only use a class when you intend on instantiating an instance of one. Else you might have a cast of sorts to a class, try to use an instance method, and then find an exception.

As with most rules, there are exceptions to this, notably when working with a framework like Nest.js that uses decorators, which will only work on classes right now — the why is a story for another time.

Something I’m on the fence about is defining the access levels of class fields in the constructors. Both of the below examples are equivalent;

class SomeClass {
  constructor(private readonly api: Api) {}
}

class SomeOtherClass {
  private readonly api: Api;
  constructor(api: Api) {
    this.api = api;
  }
}

In the first example, you can take care of it all in the constructor, whereas in the latter, you need to write more code. I could go either way really, the former is minimal and nice, but the latter loans itself to greater readability.

Ultimately, I suppose it’ll depend on the project and who’s working on it, and who will end up maintaining it.

Don’t use Namespaces

Coming from a language like .NET, you might find it acceptable and natural to use namespaces, as no denying they make sense. However, the better solution is to use modules, ES Modules to be precise.

Perhaps you’re wondering why namespaces exist in TypeScript, which is fair, but the answer is simple. When TypeScript was created ESModules didn’t exist, and some kind of solution was necessary, so that’s why TypeScript support, albeit deprecated, namespaces.

Don’t believe me? Hear it from the horse’s mouth, from Anders Hejlsberg’s interview at Inside TypeScript with Anders Hejlsberg.

Make Testing Easier

Perhaps the most frustrating part of getting up and running with TypeScript is testing.

If it’s just plain old JavaScript, everything is effectively of type any, and you can arbitrarily add functions and methods and so on to it without fail. If you’re using TypeScript, which you should, it can be a challenge.

So, without further ado, let me just say that you should be using jest-mock-extended). It makes mocking in Jest similar to Moq from .NET. Though I admit, I’m not sure what the equivalent from Java would be.

In Summary

I feel the above serves as the core of what you need to know to be up and running with TypeScript. There is, naturally, a lot more to it than this, but this should be what you need to write idiomatic TypeScript in an efficient way.

Because once you are, adding to that isn’t particularly hard. There’s a lot more out there for you to read, such as TypeScript’s Utility Types and much more.