# TypeScript

## What is TypeScript

* Superset of JavaScript
* Strongly typed
* Supports Object Oriented design
* Angular is written in TypeScript
* Easy transition from JavaScript -- looks very similar
* Similar to strongly typed languages like C# and Java
* Can auto upgrade transpiled code as browsers support new features
* Can be used on any project type where JavaScript is used.

## JavaScript vs TypeScript

### Variables

{% code title="variables.js" %}

```javascript
var foo = "Hello";  // string
var bar = false;    // false
var bam = 123;      // number

// can reassign type
foo = bar; // foo is now a boolean
```

{% endcode %}

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-2?file=src%2Fapp%2Fvariables.ts&view=editor>" %}

### Arrays

{% code title="arrays.js" %}

```javascript
var names = ['Bob', 'Mike', 'Jim'];
var ages = [10, 20, 30];
var friends = [{name: 'Bob', age: 10}, {name: 'Mike', age: 20}, {name: 'Jim', age: 30}];
```

{% endcode %}

{% code title="arrays.ts" %}

```typescript
var names: string[] = ['Bob', 'Mike', 'Jim'];
var ages: number[] = [10, 20, 30];
var friends: Object[] = [{name: 'Bob', age: 10}, {name: 'Mike', age: 20}, {name: 'Jim', age: 30}];
```

{% endcode %}

### Types in Functions

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-2?file=src%2Fapp%2Ffunction.ts&view=editor>" %}

### Inference

TypeScript is smart and can infer types based on what is assigned.

{% code title="inference.ts" %}

```typescript
var foo0 = 'Bob';  // inferred as a string
var bar0 = 123; // inferred as a number
var bam0;   // inferred as any

// infers the output type is a string
function greet1(name: string) {
    return 'Hello ' + name;
}
```

{% endcode %}

{% hint style="info" %}
Specifying types makes your code more readable and will make refactors later much easier.
{% endhint %}

{% hint style="danger" %}
Avoid: Use the any type sparingly and only as a last resort. It makes your code less reliable. Consider using a pipe operator if your variable needs to support multiple types.

`var foo: string | number; // accepts strings or numbers`
{% endhint %}

## Classes

TypeScript supports classes and can be used to create complex data structures

{% code title="person-0.ts" %}

```typescript
class FirstPerson {
    name: string;
    age: number;

    greet?() { // '?' signifies an optional property or method on the class
        return 'Hi, my name is ' + this.name + ' and I am ' + this.age + ' years old';
    }
}

let person0: FirstPerson = {name: 'Bob', age: 25};
let person1: FirstPerson = {name: 'Mike', age: 37};
let people0: FirstPerson[] = [person0, person1];

person0.greet();  // "Hi, my name is Bob and I am 25 years old"
```

{% endcode %}

## Class Constructors

{% code title="person-1.ts" %}

```typescript
class SecondPerson {
    name: string;
    age: number;

    constructor(name: string, age: number) {
        //  set private variables to constructor values
        this.name = name;
        this.age = age;
    }

    greet?() {
        return 'Hi, my name is ' + this.name + ' and I am ' + this.age + ' years old';
    }
}

let person2: SecondPerson = new SecondPerson('Bob', 25);
let person3: SecondPerson = new SecondPerson('Mike', 37);
let people1: SecondPerson[] = [person2, person3];

person2.greet();  // "Hi, my name is Bob and I am 25 years old"
```

{% endcode %}

## Class Constructor - Public params

{% hint style="info" %}
Declaring parameters as public on the constructor dynamically adds a public variable to the class and no assignment is necessary.
{% endhint %}

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-2?file=src%2Fapp%2Fperson-2.ts&view=editor>" %}

{% hint style="info" %}
Classes also support private and protected scoping on variables and work just like any other strongly typed language
{% endhint %}

## Interfaces

TypeScript supports interfaces and enforces interface contracts. If a class implements an interface it has to implement all of the properties and methods of the interface.

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-2?file=src%2Fapp%2Fperson-3.ts&view=editor>" %}

## ES6 Modules

TypeScript supports exporting classes, interfaces, modules, functions, and variables to be used in other files.

{% code title="person-interface.ts" %}

```typescript
export interface IPerson {
    name: string;
    age: number;
    greet?(): string;
}
```

{% endcode %}

{% code title="person.ts" %}

```typescript
import { IPerson } from './person-interface';

export class Person implements IPerson {

    constructor(public name: string, public age: number) {}

    greet() {
        return 'Hi, my name is ' + this.name + ' and I am ' + this.age + ' years old';
    }
}
```

{% endcode %}

{% code title="person-component.ts" %}

```typescript
import { Person } from './person';

let person1: Person = new Person('Bob', 25);
let person2: Person = new Person('Mike', 37);
let people: Person[] = [person1, person2];

person1.greet();  // "Hi, my name is Bob and I am 25 years old"
```

{% endcode %}

## Var, Let, Const?

What is the difference and when do I use which?

* Var
  * Part of JavaScript and supported by TypeScript
  * Are scoped to a function
  * Are easily created as globals and have bad consequences
* Let
  * Introduced in TypeScript
  * Prefer over Var
  * Block scoped
* Const
  * Only assigned once
  * Cannot be reassigned
  * An object's properties can be reassigned

## Arrow Functions

Otherwise known as fat arrow functions and sometimes called a lambda function.

* Don't have to keep typing function
* The `this` value of the enclosing lexical scope is used
* lexically captures meaning of arguments
* Commonly used with RxJs

```typescript
this.configService.getConfig()
    .subscribe((data: Config) => {
        this.config = data;
    });
```

## Template Strings

String concatenation can be messy and slow. Consider this:

{% code title="template-strings.ts" %}

```typescript
let name = 'Bob';
let age = 25;

console.log('hello my name is ' + name + ' I am ' + age + ' years old');

vs

console.log(`hello my name is ${name}, and I am ${age} years old`);

```

{% endcode %}

* Uses back-tick character to indicate string
* Tokens are replaced with variable values, i.e., ${variable-name}
* Can be multiline

## Generics

Allows functions and classes to work with a variety of types instead of just one. This concept is borrowed from languages like C# and Java.

{% code title="some-function.ts" %}

```typescript
// convert to allow multiple types
function someFunction1(arg: any): any {
    return arg;
}

// convert to generic
function someFunction2<T>(arg: T): T {
    return arg;
}
```

{% endcode %}

The Angular HttpClient uses generics to enforce the type returned by our API call.

{% code title="config-service.ts" %}

```typescript
import { Config } from './models/config';

getConfig() {
  // now returns an Observable of Config
  return this.http.get<Config>(this.configUrl);
}
```

{% endcode %}

## Generics with Types

Sometimes our functions need to enforce that the parameter follows a given contract.

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-3?file=src%2Fapp%2Fgenerics-with-types.ts&view=editor>" %}

## TypeScript Transpilation

Browsers don't understand TypeScript, so it must be transpiled to JavaScript.

* `tsc` transpiles TypeScript to JavaScript
* `tsconfig.json` is used to configure `tsc`
* The Angular CLI handles calling `tsc`&#x20;

## Summary

* Differences between JavaScript and TypeScript
* Classes, constructors, and interfaces
* Modules
* Arrow functions
* Template Strings
* Generics
