I'm trying to narrow a type without introducing a new block scope:
type OptionalUser = Request & { user?: User }
type RequiredUser = Request & { user: User }
function handler(request: OptionalUser) {
isAuthenticated(request) // adds user to request, throws if it can't add it
request.user // request is now RequiredUser, same block scope as isAuthenticated
}
Is there a way to type isAuthenticated
in such a way that the type of request
is narrowed down in the same block scope of handler? I know I could use a function that returns a type predicate but then the narrowed type would only exist inside the block scope of an if
statement. And if I were to have multiple functions like this it would cause a block scope hell.
CodePudding user response:
As caTS says it, assert functions are the way to go.
type User = {};
type OptionalUser = Request & { user?: User }
type RequiredUser = Request & { user: User }
function handler(request: OptionalUser) {
isAuthenticated(request) // asserted
request.user // User
}
function isAuthenticated(request: OptionalUser): asserts request is RequiredUser {
if (request.user === undefined) {
throw new Error("No user");
}
}