Treci la conținutul principal

Generice de bază în TypeScript

Genericele îți permit să creezi „variabile de tip” — substituenți pentru un tip care este completat mai târziu. Le poți folosi în clase, funcții și aliasuri de tip, astfel încât acestea să nu fie nevoite să numească tipurile exacte cu care lucrează.

Genericele fac mai ușoară scrierea de cod care poate fi reutilizat cu multe tipuri diferite.


Funcții

Funcțiile generice sunt mai generale: ele funcționează cu orice tip, descriind în același timp cu exactitate tipurile de intrare și de retur.

Notă: TypeScript poate, de asemenea, să deducă parametrii de tip generici din argumentele pe care le transmiți, așa că de multe ori nu este nevoie să îi scrii explicit.

Exemplu

S și T sunt variabile de tip. Apelul le completează ca string și number, așa că rezultatul are tipul [string, number].

Prompt
Arată o funcție generică cu doi parametri de tip. Scrie o funcție createPair<S, T> care primește v1: S și v2: T și returnează tuplul [S, T], apoi afișează createPair<string, number>('hello', 42) astfel încât rezultatul să fie tabloul [ 'hello', 42 ].
Ieșire: program TypeScript și rezultatul capturat

Clase

Genericele pot face generală și o clasă, precum Map, clasa integrată care funcționează cu orice tipuri de chei și de valori.

Notă: TypeScript poate deduce parametrul de tip generic al unei clase atunci când acesta este folosit într-un parametru al constructorului.

Exemplu

NamedValue<number> face ca T să fie number, așa că setValue acceptă doar numere.

Prompt
Arată o clasă generică al cărei tip de valoare stocată este un parametru de tip. Scrie o clasă NamedValue<T> cu un câmp privat _value: T | undefined, un constructor care primește private name: string, setValue(value: T), getValue(): T | undefined și un toString() care returnează „name: value”; creează new NamedValue<number>('myNumber'), setează valoarea la 10 și afișează toString(), obținând „myNumber: 10”.
Ieșire: program TypeScript și rezultatul capturat

Aliasuri de tip

Genericele în aliasurile de tip îți permit să creezi tipuri care pot fi reutilizate cu multe tipuri interioare diferite.

Notă: La fel funcționează și pentru interfețe, cu sintaxa interface Wrapped<T> {

Sintaxa unui alias de tip generic

Wrapped<T> este un tip de obiect al cărui value are tipul pe care îl transmiți, de exemplu number.

script.ts
type Wrapped<T> = { value: T };

const wrappedValue: Wrapped<number> = { value: 10 };

Valoare implicită

Un parametru de tip generic poate avea o valoare implicită. Valoarea implicită este folosită atunci când nu se dă niciun tip și niciunul nu poate fi dedus.

Parametru de tip implicit

T = string înseamnă că new NamedValue('myNumber'), fără un argument de tip, folosește string pentru T.

script.ts
class NamedValue<T = string> {
  private _value: T | undefined;

  constructor(private name: string) {}

  public setValue(value: T) {
    this._value = value;
  }

  public getValue(): T | undefined {
    return this._value;
  }

  public toString(): string {
    return `${this.name}: ${this._value}`;
  }
}

let value = new NamedValue('myNumber');
value.setValue('myValue');
console.log(value.toString()); // myNumber: myValue

Extends

Poți adăuga restricții unui generic pentru a limita tipurile permise.

O restricție îți permite să te bazezi pe un tip mai specific atunci când folosești variabila de tip.

Notă: O restricție poate fi combinată cu o valoare implicită.

Restricționarea unui parametru de tip

S extends string | number înseamnă că pentru S pot fi transmise doar șiruri și numere, așa că valorile pot fi afișate în siguranță.

script.ts
function createLoggedPair<S extends string | number, T extends string | number>(v1: S, v2: T): [S, T] {
  console.log(`creating pair: v1='${v1}', v2='${v2}'`);
  return [v1, v2];
}