microsoft / microsoft/TypeScript
Contextual parameters inferred from overloads improvements
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.4k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 117
Beschreibung
🔍 Search Terms
contextual parameters functions overloads inference TS7006 argument length
✅ Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ Suggestion
Currently, inferring a parameter type from a function with overloads is very finicky. Unused generic parameters, constraints, and parameter length all unnecessarily prevent parameter types from being inferred.
A lot of these limitations are mentioned on https://github.com/microsoft/TypeScript/pull/42620, but there's no inherent reason the parameters can't be inferred in many of these cases. This is a suggestion to revisit some of the merge logic to allow a wider variety of cases to be inferred correctly.
📃 Motivating Example
Here are some examples I've run into recently that I believe are reasonable inference candidates:
Playground: https://tsplay.dev/N5YkVN
export type Fn = {
// t is unused in the first overload
<t>(s: string): void
<t>(t: t): void
}
// first: string | t
export const fn: Fn = (first) => {}
export type Fn2 = {
// remove unused generic param
(s: string): void
<t>(t: t): void
}
// Parameter 'first' implicitly has an 'any' type.
export const fn2: Fn2 = (first) => {}
export type Fn3 = {
<t>(s: string): void
// add constraint to a parameter
<t extends number>(t: t): void
}
// Parameter 'first' implicitly has an 'any' type.
export const fn3: Fn3 = (first) => {}
export type Fn4 = {
(s: string): void
(n: number, b: boolean): void
}
// Second could safely be inferred as boolean | undefined here
// Type '(first: number, second: boolean) => void' is not assignable to type 'Fn4'.
// Target signature provides too few arguments. Expected 2 or more, but got 1.(2322)
export const fn4: Fn4 = (first, second) => {}
💻 Use Cases
- What do you want to use this for? Parameter inference
- What shortcomings exist with current approaches? Duplicate definitions and casting
- What workarounds are you using in the meantime? Forcing the signatures to align with hacks like adding unused generic parameters, manually typing them and/or casting.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit der Überprüfung der in TypeScript PR #42620 besprochenen Logik zum Zusammenführen von Überladungen und reproduziere die vier Beispiele im verknüpften Playground. Vergleiche die aktuelle Inferenz und die Diagnosen für Fn bis Fn4; abgeschlossen ist die Aufgabe, wenn die beabsichtigten Parametertypen inferiert werden, ohne das bestehende Laufzeitverhalten zu ändern oder bestehende Fälle zu beeinträchtigen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- compilers
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 32/100