Reputation: 1235
I feel like there may be some documentation I'm missing here, but basically what I'm trying to do is something like the following:
class Agent {
public world: World | undefined;
//...
checkWorld(): this.world is World {
return this.world !== undefined;
}
}
Such that in a different function I could do something along the lines of the following:
const agent = new Agent();
if(!agent.checkWorld()) {
throw new Error("No world assigned to agent");
}
// Handle the agent as appropriate, knowing the world exists
However, typescript is certainly not happy with the checkWorld(): this.world is World
syntax, saying 'All declarations of 'world' must have identical modifiers. My current solution is simply
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
However, this seems less than ideal. It's certainly possible this is something that I can't implicitly handle in typescript.
Of course, something like the following works:
checkWorld(w: World | undefined): w is World {
return w !== undefined;
}
//...
if(!checkWorld(agent.world)) {
throw new Error('No world assigned to agent');
}
But typescript isn't automatically acknowledging that agent.world isn't undefined past that point, so something like agent.world = agent.world as World
is still necessary.
EDIT: I know this example is somewhat contrived, because the union type is only World or undefined, but in the actual code I have a host of different world types, and would like to do a type check if it's a specific type of world.
Upvotes: 1
Views: 252
Reputation: 84982
Here's one option. Rather than trying to narrow the type on this.world
, narrow it on 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.
Upvotes: 4