microsoft / microsoft/TypeScript

Generic parameter type checking stops too early

Aperta
#59,049 10 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

In Discussion Suggestion
Lingua principale
Go
Stelle
111k
Fork
14.4k
Merge medio
1g 19h
PR unite (30g)
117

Descrizione

🔎 Search Terms

generic, early, permature, defer

🕗 Version & Regression Information
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
⏯ Playground Link

https://www.typescriptlang.org/play/?ssl=10&ssc=1&pln=1&pc=1#code/JYOwLgpgTgZghgYwgAgEoRgeQEYCsIJgA8AKgHzIDeAUMncggK5RQTgBcyJyAPsiIwA2g6gF9q1ACYFBcVshiMQhYAHsQySAGcwACgAendFjwFiAgLbZoZAJScAbquCSA3FJlyUi5WDUaAcwgwY117NAwcfEIiS2soXn4hQTJ3akFg5AdkAF5kIJCMMPdtPQdbdyA

💻 Code
interface RefObject<T> {
    current: T | null
}

declare function test(x: RefObject<number>): void;
declare function getRef(): RefObject<number | null>;

let v = getRef();
test(v);
🙁 Actual behavior

In the above code, RefObject is defined to always accept null in its current property. However, if one explicitly writes RefObject<number | null> and passes the result to a parameter accepting RefObject<number> TS reports a type error even though the types of the current property would have been the same. This happens with any type, not just null (e.g. if the definition of current was T | string.

🙂 Expected behavior

Since the current properties are equivalent after substituting the generic parameters, there should be no error. It seems like TS is stopping as soon as it sees RefObject<number | null> vs RefObject<number> even though substituting the generic parameter would result in the same type. This can be confirmed by creating a copy of the RefObject type like this:

interface RefObject<T> {
    current: T | null
}

interface RefObject2<T> {
    current: T | null
}

declare function test(x: RefObject<number>): void;
declare function getRef(): RefObject2<number | null>;

let v = getRef();
test(v);

Playground

Additional information about the issue

This affects the change in React's types between version 18 and 19, where the RefObject type changed current from T | null to only T. The uses of RefObject should add null instead, e.g. RefObject<HTMLDivElement | null>. Making libraries compatible with both the React 18 and React 19 types is difficult due to this TS issue. If a library updates its implementation to React 19, including RefObject<HTMLElement | null> in its definitions, consumers still using React 18 types will see TS errors.

cc. @eps1lon in case you know about this

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia eseguendo le riproduzioni collegate di TypeScript Playground e confronta i casi RefObject e RefObject2. Traccia il percorso del controllo dei tipi per l'istanza generica e l'assegnabilità strutturale; l'issue non indica file o test del repository. Il lavoro è completato quando i tipi delle proprietà sostituiti equivalenti vengono accettati senza compromettere il comportamento esistente del controllo generico.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.