microsoft / microsoft/TypeScript

bind, call and apply do not work on unions of function types with different return types.

Offen
#33,815 2 Kommentare 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

TypeScript Version: 3.6.3

Search Terms:
call, bind, apply, function, functions, Function.prototype.call, Function.prototype.apply, Function.prototype.bind, union, return, this, strictBindCallApply
Code

type aFn = (this: string, value: string) => string;
type bFn = (this: string, value: string) => Promise<string>;

function callFn(callback: aFn | bFn): Promise<string> | string {
    return callback.call("hello", "world");
}

function applyFn(callback: aFn | bFn): Promise<string> | string {
    return callback.apply("hello", ["world"]);
}

function bindFn(callback: aFn | bFn): () => Promise<string> | string {
    return callback.bind("hello", "world");
}

Expected behavior:
Code compiles. The types in this code are equivalent to the types in the following example, which does compile:

type cFn = (this: string, value: string) => string | Promise<string>;

function callFn1(callback: cFn): Promise<string> | string {
    return callback.call("hello", "world");
}

function applyFn1(callback: cFn): Promise<string> | string {
    return callback.apply("hello", ["world"]);
}

function bindFn1(callback: cFn): () => Promise<string> | string {
    return callback.bind("hello", "world");
}

The only difference between the two examples is that the first uses a type union of function types aFn and bFn, which only differ in terms of return value, whereas the second uses a type union in the return value of cFn. In other words I think the union of type aFn and bFn should behave the same as type cFn.

type aFn = (this: string, value: string) => string;
type bFn = (this: string, value: string) => Promise<string>;
type cFn = (this: string, value: string) => string | Promise<string>;

Actual behavior:

example.ts(5,12): error TS2684: The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", args_0: string) => string'.
  Type 'bFn' is not assignable to type '(this: "hello", args_0: string) => string'.
    Type 'Promise<string>' is not assignable to type 'string'.

example.ts(9,12): error TS2684: The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", value: string) => string'.
  Type 'bFn' is not assignable to type '(this: "hello", value: string) => string'.
    Type 'Promise<string>' is not assignable to type 'string'.

example.ts(13,12): error TS2769: No overload matches this call.
  Overload 1 of 6, '(this: (this: "hello", arg0: "world") => string, thisArg: "hello", arg0: "world"): () => string', gave the following error.
    The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", arg0: "world") => string'.
      Type 'bFn' is not assignable to type '(this: "hello", arg0: "world") => string'.
        Type 'Promise<string>' is not assignable to type 'string'.
  Overload 2 of 6, '(this: (this: "hello", ...args: "world"[]) => string, thisArg: "hello", ...args: "world"[]): (...args: "world"[]) => string', gave the following error.
    The 'this' context of type 'aFn | bFn' is not assignable to method's 'this' of type '(this: "hello", ...args: "world"[]) => string'.
      Type 'bFn' is not assignable to type '(this: "hello", ...args: "world"[]) => string'.
        Type 'Promise<string>' is not assignable to type 'string'.

Playground Link:
https://www.typescriptlang.org/play/index.html?ssl=30&ssc=2&pln=1&pc=1#code/PTAEBcAsFMGdtNAHgQwLYAcA2dQBMB7UAOwPFAHcCAnAawChwBPDBFAMWNAF5QAKKAEtYALlCxw1QcQDmAGlAA3FFgCu0MRKmyAlDwB84ydJkBuRiwQAjTj35DRR7fKUr1m47oOgACtQJowtAAPFom+ub0AGaqxADG4IIEXHEqWJx8qVhYVihxtGIcXAA+oDbEOmJ+AUGhnjKGpWGyoADe9KCdoNTQ4KrUKWm5+QB0WVh8AEQw2QSTCpNU1Fh4kzrmAL700bEJSVwoGNhMGePDBaBFoKXllb7+gfB1zo1OJm0dXT19A6BnebQRodjlMZlg5goANqLGgrSYAXXW9C2O3iiWSZWkeFOQwBhVsN04dz4em4hmqjxCzQa1zeLXaXW6vX6g2y5xGVixoOgs3moBhy1WSJRIAgMHgiFQmBw+CISwYzFYf1svAEkGEHmcCmUag0dJkpMM1NpFNq1Ii2xiaP2fzSnAAjJlcfkxHEiVUHmb6q9jQyvszfv9RuNubyFks4cLLbt0QcjlgTsRHUGLm6Kh6ak9zbTfZ9Ot8Wba2QCgfGmKHwXzoRHVojNtHrRjOcRsUmncWXcr0-xDfdM1TvTn6h9GQXA87Ac28BWIfya2tNkA

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 damit, das union-of-function-types-Beispiel im verlinkten TypeScript Playground zu reproduzieren, und vergleiche es anschließend mit dem äquivalenten union-return-type-Beispiel. Verfolge die Behandlung von call, apply und bind für Unions im Compiler; die Aufgabe ist abgeschlossen, wenn alle drei Beispiele mit den erwarteten Rückgabetypen kompiliert werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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