用户定义的警卫不再工作了?

时间:2016-10-28 21:45:48

标签: typescript typescript2.0

以下代码在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
}

编译器似乎并不认为a在else分支中是Pessoa。我错过了什么吗?

1 个答案:

答案 0 :(得分:2)

确切的错误是:

  

物业&#39; morada&#39;在类型&#39;从不&#39;

上不存在

你获得它的原因是因为编译器足够聪明,可以看到else部分永远不会被访问。

您正在做:

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

因此,如果您确定Aluno,那么它永远不会是Pessoa

有关never type的更多信息。

修改

重要的是编译器会限制devloper做出错误的事情 许多javascript开发人员会争辩说打字稿是简化的,不需要类型,但你仍然在这里使用它。

您收到的错误非常重要,因为Unreachable code错误:

function fn(): boolean {
    return false;

    let a = 3; // Error: Unreachable code detected
}

code in playground

为什么要包含从未执行的代码部分?
它就像没有它们一样,加上用代码和更改维护它们的麻烦,并在处理代码时将它们考虑在内。

第二次编辑

编译器不会检查整个流程,因此只有当编译器在当前范围内检测到时,您才会收到错误消息。
Unreachable code错误相同:

function fn(): boolean {
    throw new Error("error");
}

let a = fn();
if (a) { // no error
    console.log("all good");
}

可是:

let a = fn();
throw new Error("error");
if (a) { // Error: Unreachable code detected
    console.log("all good");
}