generics - Assosierte typer i TypeScript


I Swift finnes det et slikt konsept som tilknyttede typer.

protocol Container {
    associatedtype ItemType // Here it is.
    mutating func append(item: ItemType)
    var count: Int { get }
    subscript(i: Int) -> ItemType { get }
}

struct IntStack: Container {
    typealias ItemType = Int // Here again.
    mutating func append(item: Int) {
        self.push(item)
    }
    var count: Int {
        return items.count
    }
    subscript(i: Int) -> Int {
        return items[i]
    }

    var items = [Int]()
    mutating func push(item: Int) {
        items.append(item)
    }
    mutating func pop() -> Int {
        return items.removeLast()
    }
}

Det er en slags generiske grensesnitt, men en viktig egenskap ved tilknyttede typer er at de kan refereres til fra utsiden av den inneholdende typen.

var x: IntStack.ItemType = someIntStack.pop()

Er det mulig å lage noe slik i TypeScript?

Svar #1

Det finnes ingen slik funksjon for assosierte typer i Typescript for øyeblikket.

Alternativer til tilknyttede typer

Mens det ikke finnes noe i Typescript som dette?...

// WILL NOT COMPILE
interface Add<T> {
  type Output;

  add(other: T): Output;
}

Det finnes alternativer som kan løse noen av problemene som tilknyttede typer adresserer i varierende grad.

Slutte fra det generelle

Du kan slutte deg til typen som ble sendt til en generisk på denne måten

type ArrayItem<T> = T extends Array<infer I> ? I : never;

Og du kan bruke denne typen på denne måten.

const number: ArrayItem<Array<number>> = 1;

Du kan leke deg med det her på Typescript-lekeplassen her.

Indeksering av et felts felt

Si at du hadde noen typer som disse:

type StorageStage<T> = 
  | { kind: 'initial' }
  | { kind: 'loading', promise: Promise<Array<T>> }
  | { kind: 'loaded', storage: Array<T> };

class AsyncStorage<T> {
  state: StorageStage<T> = { kind: 'initial' };
}

Du kan bruke indekssyntaksen for å få typene til disse feltene hvis de er offentlige.

const storageStage: AsyncStorage<number>["state"] = 
  { kind: 'loaded', storage: [1] }; 

Igjen, sjekk dette på Typescript Playground her.

Relaterte artikler