Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

193
Views
How to make typescript know my variable is not undefined anymore

Here is my case:

I am using a Remix loader which get params from the URL but the params are defined as string | undefined

If the variable is undefined I would like to throw a redirection

export const loader: LoaderFunction = async ({ params }) => {
  const { myVar } = params; // myVar: string | undefined 
  definedOrRedirect(myVar, "/"); // Checks if undefined
  return fetchSomething(myVar); // myVar: string | undefined
};

Is there a way to make typescript know that if it didn't throw myVar is not undefined?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can make throwIfUndefined an assertion function to narrow the type of its argument to something that does not include undefined in its domain. An assertion function has an assertion type predicate of the form asserts x is Y as its return type, where x is the name of one of the function's parameters, and Y is the subtype of typeof X that we narrow x to assuming the function returns successfully. Assertion functions cannot return a defined value; they are basically void-returning functions.

For throwIfUndefined, here's the normal way to do it, as a function statement:

function throwIfUndefined<T>(x: T | undefined): asserts x is T {
    if (typeof x === "undefined") throw new Error("OH NOEZ");
}

You can also write it as an arrow function, although you need to explicitly annotate the variable with its type for the control flow analysis to happen correctly:

const throwIfUndefined: <T, >(x: T | undefined) => asserts x is T = x => {
    if (typeof x === "undefined") throw new Error("OH NOEZ");
}

Either way should work:

const Index = ({ params }: { params: { myVar: string | undefined } }) => {
    const { myVar } = params // myVar: string | undefined
    // myVar.toUpperCase // <-- error, Object is possibly 'undefined'
    throwIfUndefined(myVar);
    return myVar.toUpperCase() // no error now
}

try {
    console.log(Index({
        params: {
            myVar: Math.random() < 0.5 ? "hello" : undefined
        }
    })) // 50% "HELLO" 
} catch (e) {
    console.log(e); // 50% "OH NOEZ"
}

Playground link to code

over 4 years ago · Santiago Trujillo Report

0

You could skip definedOrRedirect and use an explicit check:

export const loader: LoaderFunction = async ({ params }) => {
  const { myVar } = params; // myVar: string | undefined 
  if (myVar == undefined) {
    return redirect("/");
  }
  return fetchSomething(myVar); // myVar: string
}

Or you could keep definedOrRedirect and declare it with an assertion as jcalz suggests:

function definedOrRedirect(variable, path): asserts variable is string
{
  if (variable == undefined) {
    return redirect(path);
  }
}

export const loader: LoaderFunction = async ({ params }) => {
  const { myVar } = params; // myVar: string | undefined 
  definedOrRedirect(myVar, "/");
  return fetchSomething(myVar); // myVar: string
}
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!