Home > OS >  Is there a way to narrow a type in the same block scope?
Is there a way to narrow a type in the same block scope?

Time:10-06

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");
  }
}

Playground

  • Related