microsoft / microsoft/TypeScript
Contextual parameters inferred from overloads improvements
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.4k
- Merge medio
- 1g 19h
- PR unite (30g)
- 117
Descrizione
🔍 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.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia esaminando la logica di fusione degli overload discussa in TypeScript PR #42620 e riproduci i quattro esempi nel Playground collegato. Confronta l’inferenza e la diagnostica attuali per Fn fino a Fn4; il lavoro è completato quando vengono inferiti i tipi di parametro previsti senza modificare il comportamento a runtime esistente né interrompere i casi attuali.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- typescript
- Ambito
- compilers
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Ferma
- Chiarezza
- Da chiarire
- Idoneità per principianti
- 32/100