Hur man skriver en generisk typ med begränsning som utökar iterable med Typescript


Jag försöker skriva den här typen:

type Pagination<I extends Iterable> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
}>;

Så att användare kan använda:

Pagination<Map<number, any>>

Men det verkar som att detta inte fungerar eftersom Iterable också kräver en generisk parameter.

Så istället blir jag kvar med

type Pagination<I> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: Iterable<I>;
}>;

Även om detta fungerar lika bra, blir typdefinitionerna nu Pagination<number> utan något sätt att ytterligare begränsa exakt vilken typ av iterabel som bör användas.

Svar #1

Du kan använda den generiska parametern för själva iterabeln istället för elementtypen, med T extends Iterable<any>

type Pagination<I extends Iterable<any>> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
}>;

Observera: om du av någon anledning behöver artikeltypen kan du använda en villkorlig typ för att extrahera den:

type Pagination<I extends Iterable<any>> = Readonly<{
  seek: number;
  limit: number;
  total: number;
  items: I;
  current: I extends Iterable<infer Item> ? Item: never
}>;

declare let map: Pagination<Map<string, number>>
map.current // [string, number]

declare let arr: Pagination<string[]>
arr.current // string

Spela

Relaterade artiklar