TypeScript Academy · leksjon

Generiske interfaces og typealiaser

Definer generiske interfaces og typealiaser, legg til begrensninger og standardverdier, og forstå når hver av dem er best egnet.

Leksjon 1 av 316 trinn

Generiske interfaces og typealiaser er en gratis leksjon i TypeScript Academy på CoddyKit. Dette er leksjon 1 av 3. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i TypeScript Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i TypeScript Academy inneholder totalt 3 leksjoner.

Introduksjon

Mål: Opprett gjenbrukbare strukturer med generiske grensesnitt og typealiaser. De skal legge til begrensninger og standardverdier, og lære viktige forskjeller.

Oversikt over leksjonen

Mål: Bruk strukturert samtidighet med coroutineScope, forstå propagasjon av unntak, og bruk verktøy for kansellering på en trygg måte.

Viktige ideer

  • coroutineScope venter på alle barn; en feil kansellerer søsken.
  • launch feiler umiddelbart i scopet; async gjør feil synlige ved await().
  • withTimeout kansellerer arbeidet etter en tidsgrense.
  • Pakk inn scope-er med try/catch for å håndtere unntak.

Generisk grensesnitt

Et generisk grensesnitt inneholder et typeparameter. Kallere setter inn konkrete typer (for eksempel Box<number>).

interface Box<T> {
  value: T;
}

const nBox: Box<number> = { value: 42 };
const sBox: Box<string> = { value: "ts" };
console.log(nBox.value, sBox.value);

Generisk typealias

Et typealias kan også være generisk og uttrykke objekter, funksjoner, unioner eller snitt.

type Pair<A, B> = { first: A; second: B };

const p1: Pair<number, string> = { first: 1, second: "one" };
const p2: Pair<boolean, boolean> = { first: true, second: false };
console.log(p1, p2);

Ventemåte for scope

coroutineScope oppretter et barnescope som fullføres først etter at barna er ferdige.

import kotlinx.coroutines.*

suspend fun doTwoTasks(): Unit = coroutineScope {
    // Both run concurrently and the scope waits for them
    launch { delay(150); println("Task A done") }
    launch { delay(100); println("Task B done") }
    // returning Unit implicitly after children complete
}

fun main() = runBlocking {
    doTwoTasks()
    println("Scope completed")
}

Feil kansellerer søsken

Hvis ett barn kaster et unntak, kansellerer scopet søsknene og kaster unntaket videre til kalleren. Bruk try/catch på kallestedet.

import kotlinx.coroutines.*

suspend fun failingGroup() = coroutineScope {
    val a = launch {
        try {
            repeat(5) { i ->
                println("A $i"); delay(60)
            }
        } finally {
            println("A cancelled")
        }
    }
    launch {
        delay(120)
        throw IllegalStateException("boom") // failure in child
    }
    a.join() // will be cancelled when sibling fails
}

fun main() = runBlocking {
    try {
        failingGroup()
    } catch (e: Exception) {
        println("Caught in caller: ${e.message}")
    }
    println("Caller continues")
}

Begrensninger

Legg til en extends-begrensning slik at T eksponerer nødvendige medlemmer (for eksempel id) for grensesnittmetodene.

interface Repository<T extends { id: number }> {
  getById(id: number): T | undefined;
  save(entity: T): void;
}

type User = { id: number; name: string };

const memRepo: Repository<User> = {
  store: [] as User[],
  getById(id) {
    return this.store.find(u => u.id === id);
  },
  save(u) {
    this.store.push(u);
  }
} as unknown as Repository<User>;

memRepo.save({ id: 1, name: "Ada" });
console.log(memRepo.getById(1));

Feil med async + await

Unntak fra async oppstår når du kaller await(); håndter dem med try/catch.

import kotlinx.coroutines.*

suspend fun parseAsync(s: String) = coroutineScope {
    val deferred = async {
        delay(50)
        s.toInt() // may throw NumberFormatException
    }
    try {
        println("Result = ${deferred.await()}") // error appears here
    } catch (e: NumberFormatException) {
        println("Handled parse error: ${e::class.simpleName}")
    }
}

fun main() = runBlocking {
    parseAsync("12")
    parseAsync("xx")
}

Standardverdier og utvidelse

Angi standardtypeparametere for en enklere bruk, og bygg videre på typer med verktøy (for eksempel Readonly<Box<T>>).

interface ApiResponse<T = unknown> {
  data: T;
  ok: boolean;
}

type ReadonlyBox<T> = Readonly<Box<T>>;

const r1: ApiResponse = { data: "ok", ok: true };      // T defaults to unknown
const r2: ApiResponse<number> = { data: 200, ok: true };
const rb: ReadonlyBox<string> = { value: "fixed" };
// rb.value = "change"; // Error: readonly

Kansellering med withTimeout

Bruk withTimeout for å avgrense arbeidet; den kansellerer barnet og kaster TimeoutCancellationException.

import kotlinx.coroutines.*

suspend fun slowOp(): Int {
    delay(300) // pretend work
    return 42
}

fun main() = runBlocking {
    try {
        val result = withTimeout(150) { slowOp() } // cancels after 150ms
        println("Got $result")
    } catch (e: TimeoutCancellationException) {
        println("Timed out and cancelled")
    }
}

Forskjeller i sammenslåing

Grensesnitt støtter deklarasjonssammenslåing. Typealiaser kan ikke slås sammen; dupliserte navn gir feil.

interface Settings { theme: string }
interface Settings { lang: string }
// Merged: Settings has { theme: string; lang: string }
const s: Settings = { theme: "dark", lang: "en" };

// type Settings = { foo: string };
// Error: Duplicate identifier 'Settings' for type aliases (no merging)

Feilregel for strukturert samtidighet

I coroutineScope, hva skjer hvis én barnekorutine feiler med et unntak?

Sjekk av grensesnitt kontra typer

Hurtigsjekk: Hvilken påstand om generiske grensesnitt kontra typealiaser er SANN?

Oppsummering

Oppsummering: Bruk generiske grensesnitt og typealiaser til å modellere gjenbrukbare strukturer. Legg til begrensninger og standardverdier, og husk: Det er bare grensesnitt som kan slås sammen.

Oppsummering

Oppsummering: Bruk coroutineScope til å gruppere arbeid; et barn som feiler, kansellerer søsknene. Håndter feil med try/catch, gjør async-feil synlige ved await(), og kanseller langvarige oppgaver med withTimeout.

Gratis å komme i gang

Lær deg TypeScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
101
Leksjoner
352

Ofte stilte spørsmål

Er leksjonen «Generiske interfaces og typealiaser» gratis?

Ja – hele teksten i «Generiske interfaces og typealiaser» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av TypeScript Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i TypeScript Academy inneholder totalt 3 leksjoner.

Hva lærer jeg i «Generiske interfaces og typealiaser»?

Definer generiske interfaces og typealiaser, legg til begrensninger og standardverdier, og forstå når hver av dem er best egnet. Du øver på TypeScript Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med TypeScript Academy?

Ingen tidligere erfaring er nødvendig. TypeScript Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 1 av 3.

Hvor lang tid tar leksjonen «Generiske interfaces og typealiaser»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne TypeScript Academy-leksjonen?

Ja. Alle TypeScript Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Generiske interfaces og typealiaser
  2. Betingede typer (introduksjon) og distribusjon over unioner
  3. Gjenbrukbare mønstre for datamodeller
← Tilbake til TypeScript Academy