microsoft / microsoft/TypeScript

TypeScript cannot always infer the correct type through a user-defined type guard using the 'is' operator.

Aperta
#57,189 4 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Domain: This-Typing Help Wanted
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
1g 19h
PR unite (30g)
117

Descrizione

🔎 Search Terms

"typeguard", "is operator"

🕗 Version & Regression Information

Tested with typescript@5.1.3 and later

⏯ Playground Link

No response

💻 Code
enum kind {
	a = 'a',
	b = 'b',
	c = 'c'
}

type ID = {
	id: number
}

class Test<T extends kind> {
	value: T extends kind.a | kind.b ? ID : undefined
	type: T

	constructor(
		type: T,
		value: T extends kind.a | kind.b ? ID : undefined
	) {
		this.type = type
		this.value = value
	}

	hasID(): this is Test<Exclude<kind, kind.c>> {
		return this.type !== kind.c
	}

	do() {
		if (this.hasID()) {
			return this.value.id // Error: this.value: Object is possibly 'undefined'
			// return (this as Test<Exclude<kind, kind.c>>).value.id // this works
		}
	}
}
🙁 Actual behavior

TypeScript cannot infer that 'this' is of type 'Test<Exclude<kind, kind.c>>' even though there is a type guard. In the 'do' method, TypeScript throws a TSError stating that 'this.value': Object is possibly 'undefined'.

If we explicitly cast 'this' as 'Test<Exclude<kind, kind.c>>', we can access the 'value' attribute, and it works as it should. However, somehow the type guard does not have the same effect.

🙂 Expected behavior

Since there is a type guard around the 'this.value.id' line, TypeScript should handle 'this' as a 'Test<Exclude<kind, kind.c>>' type. At least, that's what type guards are for in my understanding.

Additional information about the issue

No response

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 con la riproduzione TypeScript fornita e traccia il modo in cui il type checker restringe this dopo il type guard definito dall’utente hasID(). Aggiungi un test di regressione del compilatore per l’accesso previsto a this.value.id, quindi verifica che la diagnostica venga rimossa senza indebolire i controlli per il caso kind.c.

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
25/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.