microsoft / microsoft/TypeScript
Ensure 'in' does not operate on primitive types
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
Bug Report
🔎 Search Terms
operator in exception crash unhandled
🕗 Version & Regression Information
This is the behavior in every version I tried
⏯ Playground Link
Playground link with relevant code
💻 Code
const mustBeObject = (thing: object) => thing
const hasKey = <A extends object | null | string | number, K extends string | number | symbol>(
thing: A,
key: K,
): boolean => {
if (thing && typeof thing === 'object') {
mustBeObject(thing);
return key in thing; // no error
}
return key in thing; // error
};
hasKey(123, 'hello');
🙁 Actual behavior
TS should expect A to be an object
🙂 Expected behavior
TS didn't detect the potential crash
This is a follow-up to #41317. In #41928, we decided that we should implement a more conservative check that only ensures that the resolved constraint of the right operand to the in operator is not assignable to a primitive. This is a negative check ensuring that the type of the right operand does not explicitly extend a primitive type. This solution does not yet cover the original example shown above.
The alternative we discussed was a positive check that the type of the right expression cannot possibly extend a primitive type. We could do this either by checking that the type of right operand (not its resolved constraint!) is not assignable to a primitive or by checking that this type is assignable to object.
I am reopening this issue because with #43183 (🎉) the original reason why we went with the more conservative (from a breaking change point of view) check will soon not be a limitation any more. Therefore, code like
if (typeof val === 'object' && '__isMaybe' in val) {
does not represent a problem anymore because val can be narrowed even if its type is a type parameter as long as it extends a union (see https://github.com/microsoft/TypeScript/pull/41928#issuecomment-743356094 for the original discussion).
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 dal TypeScript Playground collegato e dall’esempio dell’operatore in, quindi leggi la discussione su #41317, #41928 e #43183. Confronta la gestione attuale degli operandi destri generici con il crash indicato per un tipo primitivo; il lavoro è completato quando il checker rifiuta in modo affidabile le espressioni in non sicure senza compromettere il comportamento di narrowing descritto nell’issue.
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