Typescript

Mer av

Repetition

  • Varför Typescript?
  • Vilka inbyggda typer finns det?
  • Hur kan man typa objekt?
  • Arrayer?
  • Funktioner?
  • Vad är unions?

Agenda

  • Types vs Interfaces
  • Objekt med dynamic keys (index signatures)
  • Enums
  • Generics

Type aliases vs interfaces 

  • Vi kan specifiera hur t.e.x ett objekt ska se ut med type eller interface. Objekttypen får ett tydligare namn och konventionen är att börja med stor bokstav.
  • Oftast kan vi använda oss av antingen type eller interface, men det finns skillnader.

Type aliases vs Interfaces 

  // I många fall helt utbytbara

  type Poet = { 
    born: number | string ; 
    name: string;
    dead?: number
  };


  interface Poet { 
    born: number | string ; 
    name: string;
    dead?: number;
  }

Interfaces 

  • Kan "extendas"  från andra interfaces
  • Keyword extends

 interface BaseAdress { 
    fullname: string;
    street: string;
    city: string;
    country: string;
  } 

 interface AdressWithPhoneNumber extends BaseAdress {
    phone: number;
 }

Interfaces 

  • Kan användas i klasser (class)
  • Keyword  implements
  interface IUser {
      id: number;
      name: string;
      displayInfo(): void;
  }


  class User implements IUser {
      id: number;
      name: string;

      constructor(id: number, name: string) {
          this.id = id;
          this.name = name;
      }

      displayInfo(): void {
          console.log(`ID: ${this.id}, Name: ${this.name}`);
      }
  }

  const user = new User(1, 'Alice');
  user.displayInfo();

Interfaces 

  • Interfaces är "öppna". Mer heuristiska.
  
  interface Person {
      name: string;
  }

  interface Person {
      age: number;
  }

  let person: Person = {
      name: 'John',
      age: 25
  };

Type aliasis

  • Objekt med type kan använda unions/intersections
// En typ är antingen en typen eller den andra
 type User = SuperUser | Admin;
// Kombinerar "ärver" typer
 type SpecialDate = Date & { getReason(): string }

Type alias eller interface?

  • Om du vill använda union eller intersection på objekt => använd type
  • Om du vill att dina objekt ska kunna ärva eller kunna mergas  eller implementeras till klasser=> använd interface
  • Om ditt objekt ska konsumeras och utvidgas till andra delar av din kodbas eller utanför (API) => använd interfaces
  • Enligt TS-teamet är interfaces något snabbare. Men det gäller ju endast under kompileringsfasen
  • Interfaces ger tydligare felmeddelanden
  • Däremot ger Type ett tydligare innehåll när man hovrar över

Type alias eller interface?

Type alias eller interface?

"For the most part, you can choose based on personal preference, and TypeScript will tell you if it needs something to be the other kind of declaration. If you would like a heuristic, use interface until you need to use features from type." - se TS-dokumentation

Type alias eller interface?

  • Var konsekvent , tills du stöter på skillnader
  • Finns säkert en konvention hos LIA-anordnare - var bekant med skillnaderna
  • På provet kommer båda accepteras så länge tsc-kompilatorn inte klagar

 

Index Signatures



  interface StringDictionary {
      [index: string]: string;
  }

  const myDict: StringDictionary = {
      prop1: "value1",
      prop2: "value2"
  };

  myDict["prop3"] = "value3";

  console.log(myDict.prop3); // Output: value3

Spara properties med dynamiska nycklar (keys)

Enums

  
  enum CardSuit {
      Clubs,
      Diamonds,
      Hearts,
      Spades
  }

  // Sample usage
  const card = CardSuit.Clubs;

  // Safety
  card = "not a member of card suit"; // Error : string is not assignable to type `CardSuit`

Ett sätt att organisera relaterad data. 

Enums

  
  enum Color {
      Red,     // 0
      Green,   // 1
      Blue     // 2
  }

  enum Color {
      DarkRed = 3,  // 3
      DarkGreen,    // 4
      DarkBlue      // 5
  }

Har ett number associerat, men går också att ändra.

Enums

  
  enum Color {
      Red,     // 0
      Green,   // 1
      Blue     // 2
  }

  
  interface Shape {
      type: string;
      color: Color[];
  }

  const chape : Shape = {
      type: "circle",
      color:  [Color.Red, Color.Green, Color.Blue]
  }

Kan exempelvis användas som uppräkning i interface

Generics

Hur kan vi ange en typ som för varje returtyp motsvarar samma input-typ??  Utan union( string | number) eller any??

  
  function convertToArray(input: string): string[]  {
      return [input]
  }

  convertToArray("hello world")
  convertToArray(1) // Error: Argument of type '1' 
	// is not assignable to parameter of type 'string'.

Svar: Genom att använda en s.k generisk typ

Generics

En generisk typ är som ett funktionsargument fast för typer.

T är en konvention, kan egentligen heta vad som helst.
T härleds till att i första fallet vare en string och andra fallet till en number

  
function convertToArray<T>(input: T): T[] {
    return [input]
}

convertToArray("hello world") //Ok!
convertToArray(1) // Ok!

Generics

... man kan också använda sig av fler generiska typer på en och samma gång

  

 function createArrayPair<T,K>(input1: T, input2: K): [T, K]{
    return [input1, input2];
 }

 createArrayPair(1, "a"); // [1, "a"]

Generics

Kan också användas i interfaces. 


  interface Burger<T> {
      size: T
      price: number
  }

  const meal: Burger<string> = {
      size: "small",
      price: 50
  }

Generics

... och i klasser

  
class Burger<T> {
    size: T
    price: number

    constructor(size: T, price: number) {
        this.size = size
        this.price = price
    }
}

const burger1 = new Burger("small", 50)
const burger2 = new Burger(3, 50)

Generics

... man kan också "begränsa" en generic med extends

  
function convertToArray<T extends number | string >(input: T): T[] {
    return [input]
}

convertToArray("hello world")
convertToArray(1)

Generics

... så vad är det bra med generics, egentligen?

  • Skapa typer som är flexibla och anpassningsbara
  • Återanvändbarhet!

Typescript - Types vs Interfaces, index signatures, enums

By sandra-larsson

Typescript - Types vs Interfaces, index signatures, enums

  • 46