Typescript 在类的成员上键入guard

Typescript 在类的成员上键入guard,typescript,Typescript,我觉得这里可能遗漏了一些文档,但基本上我想做的是如下所示: const agent = new Agent(); if(!agent.checkWorld()) { throw new Error("No world assigned to agent"); } // Handle the agent as appropriate, knowing the world exists 类代理{ 公共世界:世界|未定义; //... checkWorld():this.w

我觉得这里可能遗漏了一些文档,但基本上我想做的是如下所示:

const agent = new Agent();
if(!agent.checkWorld()) {
  throw new Error("No world assigned to agent");
} 
// Handle the agent as appropriate, knowing the world exists
类代理{
公共世界:世界|未定义;
//...
checkWorld():this.world就是世界{
返回this.world!==未定义;
}
}
这样,在不同的功能中,我可以按照以下方式执行某些操作:

const agent = new Agent();
if(!agent.checkWorld()) {
  throw new Error("No world assigned to agent");
} 
// Handle the agent as appropriate, knowing the world exists
然而,typescript肯定对
checkWorld()不满意:this.world就是world
语法,它说“world”的所有声明都必须有相同的修饰符。我目前的解决办法很简单

if(agent.world === undefined) {
  throw new Error("No world assigned to agent");
}
agent.world = agent.world as World;
// Handle the agent as appropriate, knowing the world exists
然而,这似乎不太理想。这当然有可能是我无法在typescript中隐式处理的事情

当然,类似于以下的工作:

checkWorld(w: World | undefined): w is World {
  return w !== undefined;
}
//...
if(!checkWorld(agent.world)) {
  throw new Error('No world assigned to agent');
}
但是typescript不会自动确认agent.world在该点之后没有被定义,所以像
agent.world=agent.world as world
这样的东西仍然是必要的


编辑:我知道这个例子有点做作,因为联合类型只是世界或未定义,但在实际代码中,我有许多不同的世界类型,如果它是世界的特定类型,我想做一个类型检查。

这里有一个选项。与其尝试在
this.world
上缩小类型范围,不如在
this
上缩小类型范围:

class Agent {
  public world: World | undefined;
  //...
  checkWorld(): this is { world: World } {
    return this.world !== undefined;
  }
}

const agent = new Agent();
if(!agent.checkWorld()) {
  throw new Error("No world assigned to agent");
} 
// At this point, agent's type is Agent & { world: World }
// You can write code knowing agent.world exists.

这正是我一直在寻找的解决方案!