Typescript quick reference guide and tips to get started
September 11, 2018
Like learning to ride a bicycle or flipping a pancake, some developers may get the urge to jump on the Typescript/Flow band wagon and see what the fuss is all about. This short post outlines nuggets of information I feel is helpful for beginners learning Typescript, especially for those coming from a background of developing with languages which are not strongly typed, like plain ol’ vanilla Javascript.
What is Typescript?
Typescript is a “superset” of Javascript which compiles down to plain Javascript. There are a few languages which compile down to Javascript such as Dart and Elm, but Typescript is written to look much more like traditional JS with the added feature of “Types”.
Having a “typed” language (like C# and Java) helps developers avoid errors regarding the types of their variables, constants, function parameters etc., and greatly reduces the dreaded “Uncaught TypeError: Cannot read property of undefined” errors which can send less experienced devs into a keyboard-smashing whirlwind of fury.
Furthermore, Typescript is a statically typed language which means types are checked before runtime, opposed to dynamically typed languages where types are checked during runtime. This is good for Typescript as this helps increase performance because types are already checked when the program begins. As well as better performance, this is incredible for developers as it helps reduce errors appearing at runtime, and helps make you a better developer in the process for that reason.
A real-life example in action
I find it helpful to jump straight in to examples to give something to refer to, so here’s something simple which uses a few features of Typescript:
// a simple declaration (giving a variable a type)
let isSteve: boolean
// define the Interface (object structure blueprint to check against)
interface IPerson {
firstName: string;
lastName: string;
age: number;
}
// use the Interface to set the type of the function argument
function personsDetails(person: IPerson): string {
isSteve = person.firstName == "Steve" ? true : false
if (isSteve) {
return `Steve is ${person.age} years old and last name is ${person.lastName}`
} else {
return `This person is ${person.age} years old and is called ${person.firstName} ${person.lastName}`
}
}
// call the function...
let person = {
firstName: "Steve",
lastName: "Madden",
age: 38,
}
personsDetails(person)
Declarations
A simple declaration is shown above to declare a type against the variable isSteve
. This means that the rest of the application will expect isSteve
to be either true
or false
. If it’s not either of those values when being passed into functions, classes or anywhere else, Typescript will show an error.
We may not know the value of isSteve
at runtime, but because Typescript is a statically typed language, we are able to check at compile time if isSteve
is assigned a non-boolean value. For example:
let isSteve: boolean;
function personsDetails(person: IPerson): string {
isSteve = 'Yes, this is Steve';
...
}
The above will error because isSteve
is assigned a string
type and not a boolean
type.
Interfaces
The Interface sets the “blueprint” for objects to be type checked. This is a major feature of Typescript as it allows us to ensure that an object passed around our app, such as the person
object above, has the right values within. We are told that it’s best to build an application which consists of small, broken down functions which can be re-used and help with debugging, and this is a perfect situation to be checking the types of the data which is being passed around to help this.
From the IPerson
interface defined above, the values can be set “Types”, such as the “string” and “number” types above. There are loads of types you can use which are listed in a section below.
People often prefix their Interface name with an “I” to signify that it’s an Interface and ensure it’s not confused with Class names.
Alternatives to Interfaces - types
When I was first learning Typescript, I found it odd that some tutorials wouldn’t mention Interfaces at all, and some did. Some tutorials used “Types” instead, so this Stack Overflow post will explain the difference. TL;DR: Interfaces are preferred generally, and Types are just an alias of Interfaces.
Alternatives to Interfaces - inline
Like in the above example, Interfaces can be defined externally, but they can also be defined inline while allocating a type. To follow on from the above example, the personDetails()
function can be changed to:
// we don't need to define the Interface - we can use an object to define inline instead
function personsDetails(person: {
firstName: string,
lastName: string,
age: number,
}): string {
return `This person is ${person.age} years old and is called ${person.firstName} ${person.lastName}`
}
let person = {
firstName: "Steve",
lastName: "Madden",
age: 38,
}
personsDetails(person)
I prefer to use external Interface declarations rather than inline, but that’s just my preference, especially when importing Interfaces from an external file.
Types
As mentioned above, there are many types one can use to define the structure of data. Some popular ones below:
any
- used if you want to define the type as “any”thing. It’s best to steer away from this most of the time as it makes room for errors to trickle through.boolean
- a true or false value.string
- a string.number
- a number.null
- a null value.undefined
- an undefined value.number[]
orArray<number>
- arrays of the same type.
More types can be found on the official TS site and are worth reading over before jumping straight in.
Using Types from third party libraries with @types
In our example above with the personsDetails()
function, we have our types already declared so Typescript knows what types to check against at compile time. With our own code base we can arrange these type definitions how we like, and third party Typescript libraries come with types all baked in, but what if you want to consume a standard Javascript library in your Typescript application? By default, Javascript doesn’t have a concept of types, so you either need to make your own definitions, or use existing definitions made by others.
Luckily, as Typescript is so popular, there’s a huge repository of existing type definitions for thousands of libraries over at DefinitelyTyped which is kept up to date by the general public and the Typescript team. A popular example, as you can imagine, is people using types for React. As React is built in plain Javascript, there’s a type declaration file which you can (and should) install if using React with Typescript.
To use, you’ll install React the normal way:
npm i react
Then install the types:
npm i @types/react
Notice the @types
prefix, which is used as a convention which almost all types packages follow. If you decide to use a third party lib in Typescript and you’re not sure if it has type definitions already, just try and npm i @types/[THIRD_PARTY_LIB]
and one will most likely exist.
Best way to learn
Typescript examples I found when I very first started learning Typescript weren’t too helpful as it’s generally a few small functions and variables, and doesn’t always expose you to the full landscape of Typescript (kind of like my example above…). One way which helped me with this was to develop a small Typescript application using React, allowing quick and well documented exposure to writing React components with type checking, as well as linking up to external .ts
files which can handle processing logic and helper functions.
By using a front-end application you’re familiar with, you can easily start developing something interactive and visual, keeping you excited and interested which may not be the case when coding up classes and functions for hours on end. I guess it depends on what keeps you interested and excited about a project.
I also found developing with the use of TSLint extremely useful when first starting out, and almost used this as a learning tool. You can change the level of convention to follow with the tslint.json
file, much like you do with eslint
:
{
"extends": [
"tslint:recommended",
"tslint-react",
"tslint-config-prettier"
],
"linterOptions": {
"exclude": [
"config/**/*.js",
"node_modules/**/*.ts"
]
},
"rules": {
"object-literal-sort-keys": false,
"jsx-no-lambda": false,
"member-access": true,
"no-console": false
}
}
The tslint:recommended
option contains a lot of rules, so this is perfect if you really want to follow the strictest of conventions and rules to learn in the best way.
One of the best resources for anything Typescript can be found in the official docs which isn’t always the case with
That’s it for now
Typescript is great to use, and while I think the learning curve is a little steep, it’s worth the initial time investment as it can make you a better developer as a result. You’ll also find out how nice it is using a typed language to stop annoying errors.
I’ve almost finished an all singing, all dancing web app built completely in Apollo GraphQL with Typescript, and planning to open source it as it includes examples of Typescript in many different situations. I’ll do a post about that in the next month or so, so check back later!
Thanks for reading.
Senior Engineer at Haven