microsoft / microsoft/TypeScript

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

Abierto
#57,189 4 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: This-Typing Help Wanted
Lenguaje dominante
Go
Estrellas
111k
Forks
14.4k
Merge medio
1 d 19 h
PR fusionados (30 d)
117

Descripción

🔎 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

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con la reproducción de TypeScript proporcionada y sigue cómo el comprobador de tipos estrecha this después del type guard definido por el usuario hasID(). Añade una prueba de regresión del compilador para el acceso esperado a this.value.id y, a continuación, verifica que el diagnóstico se elimine sin debilitar las comprobaciones para el caso kind.c.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
compilers
Tipo de issue
Error
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.