ConstructorParameters în TypeScript

ConstructorParameters<typeof Clasa> dă tipurile parametrilor constructorului clasei, ca tuple.

Sintaxă
type ConstructorParameters<T extends abstract new (...args: any) => any> =
    T extends abstract new (...args: infer P) => any ? P : never;

Ce face ConstructorParameters

Ca Parameters, dar pentru constructori. Primește tipul clasei (typeof Clasa, nu Clasa, care este tipul obiectelor) și dă un tuple cu parametrii lui constructor.

Este folosit în funcții „fabrică” generice, care creează obiecte dintr-o clasă primită ca argument și transmit mai departe argumentele, și împreună cu InstanceType, care dă tipul obiectului creat.

Funcționează și cu clase predefinite: ConstructorParameters<typeof Date>, ConstructorParameters<typeof Map>.

Parametri

Parametru Descriere
T Tipul unei clase (constructor), de obicei typeof NumeClasa.

Ce returnează

Un tuple cu tipurile parametrilor constructorului.

Exemple

Exemplul 1: Fabrică cu contor

class Elev {
    constructor(public nume: string, public oras: string, public clasa = "a IX-a") {}
}

let create = 0;
function creeaza(...args: ConstructorParameters<typeof Elev>): Elev {
    create++;
    return new Elev(...args);
}

console.log(creeaza("Ana", "Iași"));
console.log(creeaza("Mihai", "Cluj", "a XI-a"));
console.log("obiecte create:", create);

Rezultat

Elev { nume: 'Ana', oras: 'Iași', clasa: 'a IX-a' }
Elev { nume: 'Mihai', oras: 'Cluj', clasa: 'a XI-a' }
obiecte create: 2

Exemplul 2: Parametrii unor clase predefinite

type ArgsMap = ConstructorParameters<typeof Map<string, number>>;
type ArgsEroare = ConstructorParameters<typeof Error>;   // [message?: string, options?: ErrorOptions]

const intrari: ArgsMap = [[["Ana", 10], ["Mihai", 9]]];
const eroare: ArgsEroare = ["notă invalidă", { cause: "valoarea 12" }];

console.log(new Map(...intrari).get("Ana"));
const e = new Error(...eroare);
console.log(e.message, "|", e.cause);

Rezultat

10
notă invalidă | valoarea 12

Exemplul 3: Clasă în loc de typeof clasă

class Elev {
    constructor(public nume: string) {}
}
type A = ConstructorParameters<Elev>;
const a: A = ["Ana"];
console.log(a);

Eroarea afișată de tsc

exemplu.mts(4,32): error TS2344: Type 'Elev' does not satisfy the constraint 'abstract new (...args: any) => any'.
  Type 'Elev' provides no match for the signature 'new (...args: any): any'.
exemplu.mts(5,7): error TS2322: Type 'string[]' is not assignable to type 'never'.

Greșeli frecvente

  • Scrii ConstructorParameters<Elev>. Elev ca tip înseamnă obiectul, nu clasa; scrie typeof Elev.

Comenzi înrudite

  • InstanceType: InstanceType<C> dă tipul obiectelor create cu new dintr-un tip de clasă C.
  • Parameters: Parameters<F> dă tipurile parametrilor unei funcții, ca tuple; Parameters<F>[0] este primul parametru.
  • class: Clasele din JavaScript, cu tipuri pe câmpuri, constructor și metode, plus modificatori de acces și interfețe.
  • typeof (tip): În poziție de tip, typeof x dă tipul variabilei sau funcției x, ca să nu-l scrii de mână.