Luis Abreu Luis Abreu - 1 month ago 8
TypeScript Question

User-defined guards not working anymore?

The following code was working before the typescript 2.0:

class Aluno{
escola: string;
constructor(public nome: string){
this.escola = "";
}
}
class Pessoa{
morada: string;
constructor(public nome: string){
this.morada = "";
}
}
function ePessoa(p: Pessoa | Aluno): p is Pessoa{
return (<Pessoa>p).morada !== undefined;
}
function eAluno(p: Pessoa | Aluno): p is Aluno{
return (<Aluno>p).escola !== undefined;
}
let a: Pessoa | Aluno = new Pessoa("Luis");
console.log( a.nome ); //ok
a = new Aluno("Rui");
console.log( a.nome ); //ok
//a.escola = "teste";//erro
if(eAluno(a)){
console.log("Aluno da escola:" + a.escola);
}
else{
console.log("Pessoa residente em: " + a.morada); //morada does not exist
}


The compiler doesn't seem to consider a as being Pessoa in the else branch. Am I missing something?

Answer

The exact error is:

Property 'morada' does not exist on type 'never'

And the reason you're getting it is because the compiler is smart enough to see that the else part is never accessed.

You're doing:

let a: Pessoa | Aluno = new Pessoa("Luis");
...
a = new Aluno("Rui");

So when you get to the if it will be Aluno for sure, it will never be Pessoa.

Here more about the never type.