Exploring Typescript: Notes about the language as I learn it
Typescript is good to usee but at times it can be really infuriating to learn how to use it and to use it properly. When you bring in Javascript files to convert to Typescript it will give you many surprises and not all of them are intuitive or easy to decipher. It's important to remember that **_while Typescript will transpile to Javascript it's a superset of the ECMAScript specification, and you need to learn the differences_**. These are not all the things I've learned but they are the most important to me. ### When to add types and when to let the compiler do its thing The Typescript compiler is really good at inferring (guessing) the type of your parameters, variables or return values so it's usually OK to let it do its thing. It is only when we get an unexpected value or when the compiler gives an error that we should explicitly add types to your code. Pay particular attention when the compiler tells you that there's a type mismatch. For example, an error like `Type '1234' is not assignable to type 'string'` may indicate that we need to be explicit about types (or it may mean we made a mistake, it's always possible). Take for example the following function signature in Javascript. ```js function setRootVar(name, otname, value) {} ``` When I wrote it I instinctively knew that name and otname were strings and value was a number that would be cast as a string to accommodate CSS requirements. But Typescript saw it as this: ```typescript function setRootVar(name: any, otname: any, value: any) {} ``` The [any](https://www.typescriptlang.org/docs/handbook/basic-types.html#any) type tells the Typescript compiler to take any value you pass in and not check for validity; This defeats the purpose of type checking. To make sure that the code works as we intended it to we have to explicitly add type declarations to the parameters. As we said, the name is a string, otname is a string but it's optional and value will become a string so we'll define it as one from the beginning. ```typescript function setRootVar(name: string, value: string, otname?: string) { // body of the function here } ``` Using an optional parameter also forced me to change the order of parameters. Optional parameters must be the last ones on the list. ### Declare your types first, then build around them Typescript checks are concerned with the shape of an object and will use that shape to check if we're doing the right thing. As we start working with code either from scratch or modifying an existing codebase we may want to start by defining the types that we want to use in an interface. Let's assume that we defined a `person` interface with three values, two strings, and an optional string. ```typescript interface Person { firstName: string; lastName: string; userName: string; }; ``` Then we can use the interface everywhere we need to identify a person. Below are some examples: The first one is a person. ```typescript function createPerson(person: Person): void { console.log(person.firstName); console.log(person.lastName); console.log(person.userName); } ``` The next example is an administrator. In this example, we'll extend the Person interface with additional information that is only relevant for administrators. ```typescript interface Administrator extends Person { signedRelease: boolean; accountEnabled: boolean; } ``` Because the Administrator interface extends Person, we get everything from Person in addition to what we get from Administrator. We're saying an administrator is a person. ```typescript function createAdmin(admin: Administrator): void { // These come from Person console.log(admin.firstName); console.log(admin.lastName); console.log(admin.userName); // These come from Administrator console.log(admin.signedRelease); console.log(admin.accountEnabled); } ``` Another thing worth exploring is function overload. We can have multiple versions of a function with different parameters that perform different functions based on the type of the parameter. This is different than generic types because we do know the type of the parameters ahead of time and we code the different functions to handle them. ### Generic types One of the first things I saw and learned about Typescript was the idea of generic types. There are times when we don't know what parameters we want to use, whether the kind of parameters we want to use will change over time, or whether we will want to use the same function in different contexts. ```typescript function id