microsoft / microsoft/TypeScript

Generic constraint generates a TS2344

Offen
#36,852 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Needs Investigation
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

TypeScript Version: 3.7.x, 3.8.1, 3.9.x (next)

Search Terms: Generic constraint 2344

Code

type KeyOf<T> = keyof ((T extends any ? (k: T)=>void : never) extends ((k: infer I)=>void) ? I : never);

type Constraint<T> = KeyOf<T> extends never
  ? any
    // : KeyOf<any> extends KeyOf<T>
    // ? any
  : (
    'a' extends KeyOf<T>
      ? never
      : any
    );

type ForceConstraint<T> = T extends Constraint<T> ? T : never;

interface Interface<T extends Constraint<T>> {
  b: string;
}

type Infer<CB> = CB extends () => infer TReturn
  ? ForceConstraint<TReturn>
  : never;

type InferWithConstraint<CB> = ForceConstraint<Infer<CB>>;

type InferInterfaceFromCallback<CB> = Interface<InferWithConstraint<CB>>; // invalid => NOT OK
type InferInterfaceFromCallback1<CB> = Interface<Infer<CB>;> // invalid too => NOT OK

// just debug purpose
type A1 = Interface<unknown>;
type A2 = Interface<any>; // invalid => OK
type A3 = Interface<never>;
type A4 = Interface<undefined>;
type A5 = Interface<number>;
type A6 = Interface<string>;
type A7 = Interface<null>;
type A8 = Interface<object>;
type A9 = Interface<{}>;
type A_FAIL1 = Interface<{ a: 'b' }>; // invalid => OK
type A_FAIL2 = Interface<{ a: 'b' } | 1>; // invalid => OK

Playground Link

Expected behavior:

type InferInterfaceFromCallback<CB> = Interface<InferWithConstraint<CB>>;

Should be valid

Explanation:

So, i was trying to apply a specific constraint on a generic type.

Constraint<T> 'returns' never if T contains a property called a, else it returns any

ForceConstraint<T> tries to help typescript to know if T is valid, else it returns never

Interface<T extends Constraint<T>> forces its generic type to respect Constraint

Infer<CB> infers the return type of CB and ensures it follows Constraint

InferWithConstraint<CB> forces again Infer<CB> to be compliant with Constraint (even if it is already)

So Interface<InferWithConstraint<CB>> should be valid, sadly, typescript reports:

TS2344: Type 'ForceConstraint<Infer<CB>>' does not satisfy the constraint 'Constraint<ForceConstraint<Infer<CB>>>'.

Potentially related issues:

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

Beginne mit dem bereitgestellten Playground Link und reproduziere die TS2344-Diagnose anhand des minimalen Generik-Typbeispiels. Vergleiche die erwartete Gültigkeit von Interface<InferWithConstraint> mit dem gemeldeten Constraint-Fehler und sieh dir die verwandten Issues 31736 und 34604 an. Als erledigt gilt die Aufgabe, wenn der gültige Typalias nicht mehr TS2344 erzeugt, während die ungültigen Beispiele weiterhin abgewiesen werden.

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
35/100

Neue Issues direkt in Ihr Postfach

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