microsoft / microsoft/TypeScript

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

Offen
#30,991 12 Kommentare 44 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie mit der verlinkten Playground-Reproduktion und dem Verhalten von TypeScript 3.4 für ConstructorParameters, angewendet auf private und protected-Konstruktoren. Identifizieren Sie die relevanten Einstiegspunkte für Compiler und Regressionstests und stellen Sie anschließend ein Verhalten her, das das Tupel der Konstruktorargumente ableitet, ohne die Sichtbarkeitsprüfungen zu lockern; abgeschlossen ist die Arbeit, wenn das Beispiel mit dem erwarteten Tupel typgeprüft wird und die Testabdeckung Regressionen verhindert.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.