TypeScript Introduction

Brian Love

BrieBug Software

What are Types?

  • An API
  • A class or Interface composing properties and method signatures.

Why Use Types?

  • You're already using them as the modern web implements agreed upon APIs
  • HTMLElement !== HTMLInputElement
  • IDE/editor integration

Why does Angular use TypeScript?

  • Tooling
  • Interfaces and abstraction
  • Superset of JavaScript
  • Decorators and Aspect Oriented Programming (DI)

Basic Types

  • String
  • Boolean
  • Number
  • Array<T>
  • Object
  • Any

What's the <T> thing?

  • It's a generic
  • You specify the type (hence the commonly used "T")
  • Designated in interfaces
  • Specified in implementation

Generic Example

export class FormDataSource<T> extends DataSource<any> {

  private dataSubject: BehaviorSubject<T[]>;

  get data(): T[] {

    return this.dataSubject.value;

  }

  set data(data: T[]) {

    this.dataSubject.next(data);

  }

  constructor(data: T[], filter: Filter<T>) {

    super();

  }

}

Other Types

  • Void
  • Null
  • Undefined
  • Never
  • Enum
  • Tuple

What are Interfaces?

  • TypeScript only
  • Only used during transpiling
  • Contract for functions, properties and methods

Interface Example

export interface MarvelResponse<T> {
  status: string;
  code: number;
  data: {
    count: number;
    limit: number;
    offset: number;
    total: number;
    results: Array<T>;
  }
}

Implementation

getCharacter(characterId: number): Observable<MarvelResponse<Character>> {
  return  this.httpClient.get<MarvelResponse<Character>>(`${this.BASE_URL}/characters/${characterId.toString()}`);
}

Implement OnInit

import { OnInit } from "@angular/core";

 

export class IndexComponent implements OnInit {

  constructor() {}

  ngOnInit() { ... }

}

What are Classes?

  • Encapsulated Code
  • Single responsibility
  • Closed for modification but open for extension
  • Can implement interfaces
  • Can extend another class

What are Access Modifiers?

  • Members of a class can be denoted as public, private or protected
  • Public by default
  • Private limits to class
  • Protected limits to class and derived classes
  • Readonly is a constant that must be defined at time of declaration

Service Class

export class CharactersService extends MarvelService {
  characters: Observable<Array<Character>>;
  private shadyCharacters: Observable<Array<Character>>;
  readonly URL = 'https://localhost:4200';

  constructor(private httpClient: HttpClient){
    super();
  }

  private doSomething(withThis: number){ ... }
}

Component Class

export class IndexComponent implements OnInit {

  loading: Observable<boolean>;

  powers: Observable<Array<Power>>;

  constructor(private store: Store<PowersState>) { }

  ngOnInit() {

    this.loading = this.store.select(isPowerLoading);

    this.powers = this.store.select(getAllPowers);

    this.store.dispatch(new LoadPowers());

  }

}

What are Parameter Properties?

  • Create and initialize member properties at the same time
  • Often used in the constructor function signature

What are Accessors and Mutators?

  • Often referred to as "getters" and "setters"
  • Allow you to have fine-grained control over how a member property is accessed or mutated
  • The mutator must return void
  • Not necessary to implement both

Accessors Example

export class InstrumentManagerComponent {
  private _data = [];

  get data(): any[] {
    return this._data;
  }

  set data(data: any[]) {
    this._data = data;
    // do something else
  }
}

What are Abstract Classes?

  • Classes denoted with the abstract keyword
  • May contain one or more abstract methods
  • Cannot be instantiated directly
  • Abstract methods must be implemented by derived class

What are optional and default parameters?

  • Parameters are required by default
  • Parameters can be optional using the ? notation
  • Optional parameters must be follow all required parameters
  • Default values can be assigned to optional parameters

Parameters Example

export function doSomething(withThis?: number) {

  // code omitted

}

 

export function reducer(state: State = initialState, action: PowersAction) {

  // code omitted

}

What are Rest Parameters?

  • Gather multiple optional parameters into a variable
  • Use the ellipsis notation: ...
  • Must be the last parameter in a function/method

Rest Parameter Example

function buildName(firstName: string, ...restOfName: string[]) {

  return firstName + " " + restOfName.join(" ");

}

What is Destructuring?

  • Assign block-scoped variables from array or objects
  • Unpacks the array values to distinct variables
  • Unpacks the object properties to distinct variables

Destructuring Example

function example() {

  let input = [1, 2, 3, 4];

  let [a, b, ...c] = input;

}

 

function example2() {

  let input = {a: 1, b: 2, c: 3};

  let {a, ...b} = input;

}

What is the Spread Operator?

  • The opposite of destructuring
  • Spread the values of an array into another array
  • Spread the properties of an object into another object
  • Creates shallow clones

Spread Array Example

const showSpinnerActions = [

  ADD_POWER,

  DELETE_POWER,

  LOAD_POWER,

  UPDATE_POWER

];

@Effect()

  showSpinner: Observable<Action> = this.actions

    .ofType<showSpinnerTypes>(...showSpinnerActions)

    .pipe(map(() => new ShowSpinner()));

Spread Object Example

export function reducer(state: State = initialState, action: PowersAction) {

  switch (action.type) {

    case ADD_POWER_DIALOG_CLOSE:

      return {...state, addDialogShow: false};

  }

}

What are Overloaded Functions?

  • Supports JavaScript's dynamic style
  • Multiple function/method signatures

Overload Example

pipe(): Observable<T>;

pipe<A>(op1: OperatorFunction<T, A>): Observable<A>;

pipe<A, B>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>): Observable<B>;

pipe<A, B, C>(op1: OperatorFunction<T, A>, op2: OperatorFunction<A, B>, op3: OperatorFunction<B, C>): Observable<C>;

What are Enums

  • Defined set of constants
  • Can be either numeric or string based (2.4+)

Enum Example

export enum ReportEnum {

  DataImport = 1,

  DataSummary = 2,

  SiteEventLog = 3,

  TabularData = 4,

}

Enum Implemented

function showReport(reportType: ReportEnum) {

  switch(reportType) {

    case ReportEnum.DataImport:

      // data import report

    case ReportEnum.DataSummary:

      // data summary report

  }

}

What is Type Inferencing?

  • TypeScript compiler will infer types when not explicitly defined
  • This is a mostly good thing - let the compiler work for you!
  • Context will help the compiler to determine type

What is Type Assertion?

  • Assert the type to override inference
  • Assert the type of any
  • Assertion is compile-time not runtime

Type Assertion Example

export class AddHeroDialogComponent implements OnInit {

  characterSelected(event: MatAutocompleteSelectedEvent) {

    this.character = <Character>event.option.value;

  }

}

TypeScript Introduction

By Brian Love

TypeScript Introduction

An Introduction to TypeScript for the Angular developer

  • 1,028