microsoft / microsoft/TypeScript

Unsafe Map overload spoils direct property access on parenthesized assignment expression

Aperta
#61,506 2 commenti 2 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Domain: check: Type Inference Help Wanted Possible Improvement
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

### 🔎 Search Terms

map overload any unknown unsafe weakmap set binary assignment lazy init

### 🕗 Version & Regression Information

- This is the behavior in every version I tried

### ⏯ Playground Link

https://www.typescriptlang.org/play/?ts=5.9.0-dev.20250326#code/DYUwLgBAxghlAWIBcECyMAOAeAzmATgJYB2A5gDQQD2ARgFYhRgB8EAPhAK7EAmIAZiRA8A3ACgx-bk0JViEMCDwBGABQBrEAE8UeImQCUEAN5iI0OXgj4lnYJAC8EVbAQgIAfg9PiIAO5omKoGBgB0pOAa2gbi5gD0cebmAHoeZtbgnPjyNjh2YOIAvhJSxDJyCkpgAExROhB6JKRGpuauiJ7eEL4B6BjBsRbEVrn5EE7tIOGRmlox6QlJEKnpNmBZObb2RWJAA

### 💻 Code

```ts
let cache: Map | undefined;

function test1(key: string) {
const result = (cache ??= new Map()).get(key);
// ^? const result: any
return result;
}

function test2(key: string) {
cache ??= new Map();
const result = cache.get(key);
// ^? const result: object | undefined
return result;
}
```

### 🙁 Actual behavior

First `result` gets spoiled as `any`

### 🙂 Expected behavior

I'd expect both `result`s to be `object | undefined`

### Additional information about the issue

This bug reports an issue related to `Map` but, tbf, it's not unique to `Map` and a more general solution would have to be found to properly fix this. The problem is how `checkBinaryLikeExpressionWorker` create a union of left and right types here - without taking into consideration that the assignment target might already overlap with the right type. That union type gets reduced with `UnionReduction.Subtype` and `.get` gets read from it - instead of the assigned to reference on the left side.

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

Riproduci la differenza tra test1 e test2 usando il TypeScript Playground collegato, quindi esamina checkBinaryLikeExpressionWorker, che il report identifica come responsabile della formazione dell’unione degli operandi di assegnazione. Traccia come viene ridotta tale unione prima della risoluzione di .get. Il lavoro è completato quando l’accesso all’assegnazione tra parentesi inferisce object | undefined come la forma di assegnazione separata, con una copertura di regressione per l’esempio riportato.

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

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.