Typescript: Cum păstrează `Parameters` numele argumentelor?


Ia în considerare următorul fragment de cod:

const f = (a: number, b?: string) => 2;

type ParametersOfF = Parameters<typeof f>; // [number, string?]
type AsTuple = [number, string?]; // [number, string?]

declare function g(...args: ParametersOfF): number; // function g(a: number, b?: string): number !!!
declare function h(...args: AsTuple): number; // function h(args_0: number, args_1?: string): number

Deci ParametersOfF și AsTuple sunt același tip. Dar când definesc funcții care iau ca argumente aceste 2 tuple, g are nume de argumente bine definite a și b, în timp ce h are args_0 și args_1.

De aici și titlul acestei postări: Parameters<F> nu este un simplu tuple, conține de asemenea și numele fiecărui element din acel tuple. Privind cum este definit Parameters nu ajută, este destul de simplu. Deci care este magia?

Răspuns #1

Motivul are legătură cu internals-urile compilatorului, nu atât cu tipul Parameters în sine. Orice tip condițional similar pe care îl scrieți va păstra numele parametrilor.

Pentru tuplurile extrase din parametri, compilatorul păstrează o referință către parametrul original din care a fost extras fiecare element al tuplului. Când tuplul este răspândit înapoi către o funcție, se folosește numele original.

Această asociere nu este ceva direct vizibil din sistemul de tipuri și nu există nicio modalitate de a seta acest nume al elementului tuplu, este o proprietate ascunsă a tuplului.