microsoft / microsoft/TypeScript

ConstructorParameters is not working for private constructors (and protected constructors)

Aperta
#30,991 12 commenti 44 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Awaiting More Feedback Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

TypeScript Version: 3.4
Search Terms: ConstructorParameters, private constructor

Code

class Foo
{ public constructor(a: number, b: boolean, c: string) { } }

class Bar
{ private constructor(a: number, b: boolean, c: string) { } }

type FooCtorArgs = ConstructorParameters<typeof Foo>;
type BarCtorArgs = ConstructorParameters<typeof Bar>;

Expected behavior:
BarCtorArgs is [number, boolean, string].

Actual behavior:
Error in line 8:
Type 'typeof Bar' does not satisfy the constraint 'new (...args: any) => any'. Cannot assign a 'private' constructor type to a 'public' constructor type.

Playground Link: https://www.typescriptlang.org/play/#src=class%20Foo%0D%0A%7B%20public%20constructor(a%3A%20number%2C%20b%3A%20boolean%2C%20c%3A%20string)%20%7B%20%7D%20%7D%0D%0A%0D%0Aclass%20Bar%0D%0A%7B%20private%20constructor(a%3A%20number%2C%20b%3A%20boolean%2C%20c%3A%20string)%20%7B%20%7D%20%7D%0D%0A%0D%0Atype%20FooCtorArgs%20%3D%20ConstructorParameters%3Ctypeof%20Foo%3E%3B%0D%0Atype%20BarCtorArgs%20%3D%20ConstructorParameters%3Ctypeof%20Bar%3E%3B


Use Case

Convenient factory pattern to mimic asynchronous object construction.

class Component
{
    public static async create(...args: ConstructorParameters<typeof Component>)
    {
        const component = new Component(...args);
        await component.initialize();
        return component;
    }

    private constructor(a: number, b: boolean, c: string)
    { /* stuff */ }

    private async initialize()
    { /* asynchronous setup */ }
}

Ideas for Solution

Allow visibility modifiers in interfaces. Yes, if you use an interface to outline the visible properties of an object to a user this makes no sense, but why not allow interfaces to be a flexible tool to specify internal rules of implementations? I think this problem could be solved, if the ConstructorParameters type could be defined like the following:

type ConstructorParameters<T extends {private new (...args: any[]): any}> = T extends new (...args: infer P) => any ? P : never;

Which is of course no allowed at the moment.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia dalla riproduzione collegata in Playground e dal comportamento di TypeScript 3.4 per ConstructorParameters applicato ai costruttori private e protected. Individua i punti di ingresso rilevanti del compilatore e dei test di regressione, quindi stabilisci un comportamento che inferisca la tupla degli argomenti del costruttore senza indebolire i controlli di visibilità; il lavoro è completato quando l’esempio supera il controllo dei tipi con la tupla prevista e la copertura impedisce le regressioni.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.