A set of TypeScript related notes used for quick reference. The cheatsheet contains references to types, classes, decorators, and many other TypeScript related subjects.
TypeScript is a very powerful addition to JavaScript. TypeScript is developed by Microsoft and is increasingly supported by the day by technologies such as Angular, Vue.js 3, React.js, and many others.
As TypeScript code can be compiled to ES5, it includes all of the native JavaScript features such as spread arrow function, deconstructors, and introduces some very useful features such as decorators, generics and interfaces, enums, modules, among others which can be found in different programming languages.
TypeScript is not an entirely new language it’s a superset of JavaScript so that means any valid JavaScript code is also valid TypeScript code but TypeScript has additional features that do not exist in current version of JavaScript.
- Strong or static typing —> such as in languages like C# and Java when we define variables we need to specify the type of that variable.
- Object-oriented features —> that was not in Javascript. Now we have the concept of classes, interfaces, constructors, access modifiers like public and private available in Typescript.
- Compile-time errors —> we can catch errors at compile time instead of at runtime — not all kind of errors but a lot of errors. We can catch these errors at compile time and fix them before deploying our application.
For programs to be useful, we need to be able to work with some of the simplest units of data: numbers, strings, structures, boolean values, and the like. In TypeScript, we support much the same types as you would expect in JavaScript, with a convenient enumeration type thrown in to help things along.
Another fundamental part of creating programs in JavaScript for webpages and servers alike is working with textual data. As in other languages, we use the type string to refer to these textual datatypes. Just like JavaScript, TypeScript also uses double quotes (") or single quotes (') to surround string data.
const myName: string = 'Rupert';
As in JavaScript, all numbers in TypeScript are floating point values. These floating point numbers get the type
number
. In addition to hexadecimal and decimal literals, TypeScript also supports binary and octal literals introduced in ECMAScript 2015.
const myAge: number = 24;
The most basic datatype is the simple
true
/false
value, which JavaScript and TypeScript call aboolean
value.
const bHasHobbies: boolean = true;
TypeScript, like JavaScript, allows you to work with arrays of values. Array types can be written in one of two ways. In the first, you use the type of the elements followed by [] to denote an array of that element type:
const hobbies: string[] = ['Programming', 'Cooking'];
If no types are declared, TypeScript will automatically assign a type depending on the types of the Array values.
const numbers = [1, 3.22, 6, -1] // This variable will automatically be assigned a number[] array type.
Note that declaring types is encouraged.
Tuple types allow you to express an array where the type of a fixed number of elements is known, but need not be the same. For example, you may want to represent a value as a pair of a
string
and anumber
:
const address: [string, number] = ["Street", 99];
We may need to describe the type of variables that we do not know when we are writing an application. These values may come from dynamic content, e.g. from the user or a 3rd party library. In these cases, we want to opt-out of type-checking and let the values pass through compile-time checks. To do so, we label these with the
any
type:
let myCar: any = 'BMW';
console.log(myCar); // Prints: BMW
myCar = { brand: 'BMW', series: 3 };
console.log(myCar) // Prints: { brand: "BMW", series: 3 }
A helpful addition to the standard set of datatypes from JavaScript is the enum. As in languages like C#, an enum is a way of giving more friendly names to sets of numeric values. By default, any
enum
will begin numbering their members starting at 0. You can change this by manually setting the value of one of its members. For example, we can modify the Green value to 100, the next will be 101, then set Yellow back to 2.
enum Color {
Gray, // 0
Red, // 1
Green = 100, // 100
Blue, // 101
Yellow = 2 // 2
}
const myColor: Color = Color.Green
console.log(myColor); // Prints: 100
```<br>
### Functions
Functions as you may expect work exactly the same as in JavaScript with a couple new features. In TypeScript, you may assign the function two things:
- Argument types.
- Function types.
```ts
function returnMyName(myName): string {
return myName;
}
console.log(returnMyName('Robert')) // Prints: Robert
In TypeScript any argument of a function may be assigned a type no matter how complex, for example:
// argument types
function multiply(value1: number, value2: number) {
return value1 * value2;
}
// console.log(multiply('Robert', 5)) // Not possible, both arguments must be of type number.
console.log(multiply(10,5)) // Prints: 50
Just like the argument, the return value of a function may be assigned a type. Consider the example above to be included into the example below:
const myMultiply: (val1: number, val2: number) => number;
// myMultiply = sayHello; // Not possible.
// myMultiply(); // Not possible.
myMultiply = multiply;
console.log(myMultiply(5, 2));
The type
void
is a little like the opposite ofany
: the absence of having any type at all. You may commonly see this as the return type of functions that do not return a value:
function sayHello(): void {
console.log('Hello!');
// return myName; // Not possible because the function can't return anything due to the void assigned type (more on this below).
}
Declaring variables of type
void
is not useful because you can only assignundefined
ornull
to them:
let unusable: void = undefined;
The type
object
represents the non-primitive type, i.e. any thing that is notnumber
,string
,boolean
,symbol
,null
, orundefined
.
In JavaScript, so as in TypeScript, Objects are comprised of key-value pairs. We can assign types to the object
key-value pairs, like so:
let userData: { name: string, age: number } = {
name: 'Max',
age: 27
};
// userData = { // Not valid
// name: 2,
// age: 'Age'
// };
// userData = { // Not valid
// a: 'Robert',
// b: 24
// };
userData = {
name: 'Robert',
age: 24
};
As you may expect, the assigned types to the object
key-value pairs can reach high levels of complexity, for example:
let complex: { data: number[], output: (all: boolean) => number[] } = {
data: [100, 3,99, 10],
output: function(all: boolean): number[] {
return this.data
}
};
// complex = {}; // Not possible.
In TypeScript, all newly declared object properties (including both function parameters, and interface properties) may be declared as optional. To do so, we must place a ?
character after the key (or name) of the property when declaring it (a postfix notation). Here's an example:
const right: { name: string, age?: number } = {
name: 'Robert'
};
const alsoRight: { name: string, age?: number } = {
name: 'Robert',
age: 24
};
// This is not possible because the name key-value pair is missing.
// const wrong: { name: string, age?: number } = {
// age: 24
// };
Writing complex and long types can quickly become dull and impractical. For a DRY approach, it's possible to create aliases for types, essentially creating your own types. Here's an example using the complex object above:
type Complex = { data: number[], output: (all: boolean) => number[] };
let complex2: Complex = {
data: [100, 3,99, 10],
output: function(all: boolean): number[] {
return this.data
}
};
Variables are not restricted to only one assigned type. This is where union types come in where we can assign two or more types (e.g. assign number
and string
) to a single variable. For example:
let myRealRealAge: number | string = 24;
myRealRealAge = '24';
// myRealRealAge = true // Not possible since myRealRealAge only accepts a number or a string.
TypeScript natively supports the newer ES6 (A.K.A. ECMAScript 6 and ECMAScript 2015) JavaScript features. As you may have guessed, we can assign types to these new features (e.g. assigning types to an arrow function). Here are some examples:
const userName = 'Robert';
const greeting = `Hello I'm ${userName}`;
console.log(greeting)
Arrow function arguments can be assigned any type.
const greet = (name: string = 'Robert') => console.log(`Hello, ${name}`);
greet('Robert Molina');
Arrow functions may also be defined with default argument values in case no respective arguments were passed, these default parameters may also be of any assigned type.
const greet = (name: string = 'Robert') => console.log(`Hello, ${name}`);
greet(); // Prints: "Robert"
Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
const numbers: number[] = [-3, 33, 38, 5];
console.log(Math.min(...numbers));
const newArray: number[] = [55, 20, ...numbers];
console.log(newArray);
Arrays may also be destructured in TypeScript, keep in mind that all the assigned types to the array values won't be lost when destructured.
const testResults: number[] = [3.89, 2.99, 1.38];
const [result1, result2, result3] = testResults;
console.log(result1, result2, result3);
Just like arrays, the destructured object value pairs will keep their previously assigned types. Keep in mind that when destructuring an object, the declared variable name must match the object key to let the compiler know which variable to destructure.
const scientist: { firstName: string, experience: number } = { firstName: 'Robert', experience: 9000 };
const { firstName, experience } = scientist;
console.log(firstName, experience);
- rmolinamir typescript-cheatsheet