"Tackling Typescript" - Alex R online book

I'm a big fan of Alex Rauschmayer and his blog 2Ality because Alex is a teacher, he shares great information in his posts and free books. Often at a deeper level than many other sources. And he's a trusted resource.

We've been using Typescript for all our frontend code since 2018 and the frontend team all appreciate Typescripts benefits. But it's good to take a step back and refresh so I'm reading Alexs' book "Tackling Typescript". Typescript has become more and more popular and more and more positions require it. It's a language every javascript dev should know. Here are my notes on Alexs' book.

Alex points out that Typescript identifies errors statically but also that Typescript is also documentation of the code which is also a big plus. Once you're used to Typescript (ts) you really notice the difference when comparing to plan js code...you get much more information in the ts code. Another plus is Typescript is an early adopter of new ECMAScript features such as Classes, private/public members, arrow functions etc and more recently:
optional chaining 
   const street1 = user?.address?.street1;  // const street1 is undefined if any of the chain is undefined
   data?.map(...);                                       // map() is not called if data is null (or void 0)

and nullish
   const street1 = user?.address?.street1 ?? 'Please enter street';

interface Address {
  street1: string;
}
interface User {
  address?: Address;
}
const user:User = { address: undefined };
console.log(user?.address?.street1 ?? 'Street with no name' );

In these cases the ts code is generating nested ternary js code which progressively checks if the user then address then street is null (or void 0) and only using if not. 

But for sure there is a learning curve with Typescript and I have seen teams get discouraged by that and even stop adoption. I like Alexs recommendation about keeping things as simple as possible and avoid overdoing generics (which is more advanced). He also has a chapter on migrating to Typescript (for existing codebases we allowed a mix of js and ts and migrated incrementally and new codebases stated with Typescript)

Good resources listed in Chapter 3. I like Typescripts online playground to Run code and learn. It's useful, up to date and fast. You can run code and also look at the js code generated which is interesting to see.

Chapter 7 Essential is a meaty chapter with a lot of information covering important concepts and major elements of Javascript such as Arrays, Objects, Functions and Typescript features such as Union types and Generic (thats a lot!). I recommend this as a good overview with code examples.
Later chapters go into more detail on some of these but you have to pay for those chapters. The free Typescript docs are definitely a good alternative for such deep dives or whisper it: you may find chapter content in Alexs blog posts...wink wink, nudge nudge, say no more, say no more.
  • Typescript adds static types to Javascript. Meaning Typescript checks at compile time (or writing in ide) not at runtime.
  • Developers add type annotations to their code e.g. name:string which are called type expressions
  • Typescript can also infer static types from code that does not have type annotations which follows rules to infer types
  • callout re concept of Typescript having 2 language levels 
    • static - managed by Typescript consisting static types at compile time
      • Types exist at the static level
    • dynamic - managed by javascript consisting of code and values at runtime
      • it's important to realize all the Typescript annotations are stripped out from the generated javascript code (because Typescript is not runtime)
      • values exist at the dynamic level
  • arrays
    • e.g. let arr: number[] = []; // arr is an array of numbers
    • ts allows you to specify an array with a fixed number of elements, called a tuple
      • e.g. let x: [string, number] 
      • x = ["length", 221]  works but  x = [221, "wrong"]  fails 
  • functions annotated example with default values
    • function createPoint(x:number 0, y:number 5): [numbernumber] {
        return [x, y];
      }
    • this ^ is the way our team typically add types to functions but you can define a function type for a function like so (or you could define a totally separate type and then use that):
    • let createPoint: (xvalue?: number, yvalue?: number) => [numbernumber]
        = function(x = 0, y = 5): [numbernumber] {
        return [x, y];
      }
    • (or you could define a totally separate type and then use that)
    • you can annotate functions that return void but they must return void (explicit/implicit) and not a value 
    • optional means doesn't have to be preset but is not is undefined e.g. optional param
    • you can't mix optional and default
  • Union types - specifying more than one possible type
    • let maybeNumber: number | null;
    • if a param can be null then you to include it in the annotation and check for that when using in a function
    • example of a function with param callback that can be null but must be passed a number if provided
    • function stringify123(callback: null || ((num: number) => string) => {
  • Object types. Chapter 7 covers Objects when all the properties are known at development time, so you can define a type to cover all known cases (Objects as dynamic dictionaries covered elsewhere)
    • when all properties are known you can define a Typescript Interface which you use later
      • e.g. function displayUser(u: User) {     // types an object of type User
    • you can also use literal object types
      • e.g. const u:{ name: string, age?: number } = { name: "Denis"}
    • the text shows 2 ways to define functions in an Interface

    • Typescript will warn you about unbound this for functions in Objects so use ES6 arrow functions to bind
    • you will user Interfaces a lot
  • Generics


After this I recommend Chapter 11 "What is a Type is Typescript? Two Perspectives" OR "Type Compatibility" chapter in the Typescript Handbook
  • Typescript uses structural typing which is a way of relating types based solely on their members i.e Types are compatible based on their values
    • a is compatible with b if b has at least the same set of members as a
    • x is a subtype of y if x has all the values of y (and possibly more)
    • interestingly when comparing two object instances of a Class Type only members (including private) of the instances are compared, not methods
    • note: philosophically structural typing seems to me consistent with Javascript as a dynamic language and the idea of duck typing
  • This is in contrast to nominal typing used in languages such as C# or Java where types are based on naming and not their values. e.g. 
    • class Person extends class Human and class Engineer extends class Person. Then Engineer is a subtype of Human (subtype relationship)

Some final thoughts:
  • Stick with it, Typescript is worth it but recognize it's a more medium to long term investment due to learning curve
  • Would I recommend this books free chapters over the Typescript handbook? They do complement each other but if I had to choose one I'd go with the Typescript handbook. It has everything.
  • Typescript continues to evolve and early adopt new ECMAScript features. You have to keep up with that and keep upgrading Typescript versions.










Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more