Was this page helpful?

Conditional Types

At the heart of most useful programs, we have to make decisions based on input. JavaScript programs are no different, but given the fact that values can be easily introspected, those decisions are also based on the types of the inputs. Conditional types help describe the relation between the types of inputs and outputs.

Conditional types take a form that looks a little like conditional expressions ( condition ? trueExpression : falseExpression ) in JavaScript:

When the type on the left of the extends is assignable to the one on the right, then you’ll get the type in the first branch (the “true” branch); otherwise you’ll get the type in the latter branch (the “false” branch).

From the examples above, conditional types might not immediately seem useful - we can tell ourselves whether or not Dog extends Animal and pick number or string ! But the power of conditional types comes from using them with generics.

For example, let’s take the following createLabel function:

These overloads for createLabel describe a single JavaScript function that makes a choice based on the types of its inputs. Note a few things:

  • If a library has to make the same sort of choice over and over throughout its API, this becomes cumbersome.
  • We have to create three overloads: one for each case when we’re sure of the type (one for string and one for number ), and one for the most general case (taking a string | number ). For every new type createLabel can handle, the number of overloads grows exponentially.

Instead, we can encode that logic in a conditional type:

We can then use that conditional type to simplify our overloads down to a single function with no overloads.

Conditional Type Constraints

Often, the checks in a conditional type will provide us with some new information. Just like narrowing with type guards can give us a more specific type, the true branch of a conditional type will further constrain generics by the type we check against.

For example, let’s take the following:

In this example, TypeScript errors because T isn’t known to have a property called message . We could constrain T , and TypeScript would no longer complain:

However, what if we wanted MessageOf to take any type, and default to something like never if a message property isn’t available? We can do this by moving the constraint out and introducing a conditional type:

Within the true branch, TypeScript knows that T will have a message property.

As another example, we could also write a type called Flatten that flattens array types to their element types, but leaves them alone otherwise:

When Flatten is given an array type, it uses an indexed access with number to fetch out string[] ’s element type. Otherwise, it just returns the type it was given.

Inferring Within Conditional Types

We just found ourselves using conditional types to apply constraints and then extract out types. This ends up being such a common operation that conditional types make it easier.

Conditional types provide us with a way to infer from types we compare against in the true branch using the infer keyword. For example, we could have inferred the element type in Flatten instead of fetching it out “manually” with an indexed access type:

Here, we used the infer keyword to declaratively introduce a new generic type variable named Item instead of specifying how to retrieve the element type of Type within the true branch. This frees us from having to think about how to dig through and probing apart the structure of the types we’re interested in.

We can write some useful helper type aliases using the infer keyword. For example, for simple cases, we can extract the return type out from function types:

When inferring from a type with multiple call signatures (such as the type of an overloaded function), inferences are made from the last signature (which, presumably, is the most permissive catch-all case). It is not possible to perform overload resolution based on a list of argument types.

Distributive Conditional Types

When conditional types act on a generic type, they become distributive when given a union type. For example, take the following:

If we plug a union type into ToArray , then the conditional type will be applied to each member of that union.

What happens here is that ToArray distributes on:

and maps over each member type of the union, to what is effectively:

which leaves us with:

Typically, distributivity is the desired behavior. To avoid that behavior, you can surround each side of the extends keyword with square brackets.

Indexed Access Types

Using Type['a'] syntax to access a subset of a type.

Mapped Types

Generating types by re-using an existing type.

The TypeScript docs are an open source project. Help us improve these pages by sending a Pull Request ❤

Orta Therox  (10)

Last updated: Apr 15, 2024  

Home » TypeScript Tutorial » TypeScript if else

TypeScript if else

Summary : in this tutorial, you will learn about the TypeScript if...else statement.

TypeScript if statement

An if statement executes a statement based on a condition. If the condition is truthy, the if statement will execute the statements inside its body:

For example, the following statement illustrates how to use the if statement to increase the counter variable if its value is less than the value of the max constant:

In this example, because the counter variable starts at zero, it is less than the max constant. The expression counter < max evaluates to true therefore the if statement executes the statement counter++ .

Let’s initialize the counter variable to 100 :

In this example, the expression counter < max evaluates to false . The if statement doesn’t execute the statement counter++ . Therefore, the output is 100.

TypeScript if…else statement

If you want to execute other statements when the condition in the if statement evaluates to false , you can use the if...else statement:

The following illustrates an example of using the if..else statement:

In this example, the expression counter < max evaluates to false therefore the statement in the else branch executes that resets the counter variable to 1 .

Ternary operator ?:

In practice, if you have a simple condition, you can use the ternary operator ?: rather than the if...else statement to make code shorter like this:

TypeScript if…else if…else statement

When you want to execute code based on multiple conditions, you can use the if...else if...else statement.

The if…else if…else statement can have one or more else if branches but only one else branch.

For example:

This example used the if...elseif...else statement to determine the discount based on the number of items.

If the number of items from less than or equal to 5, the discount is 5%. The statement in the if branch executes.

If the number of items is less than or equal to 10, the discount is 10%. The statement in the else if branch executes.

When the number of items is greater than 10, the discount is 15%. The statement in the else branch executes.

In this example, the assumption is that the number of items is always greater than zero. However, if the number of items is less than zero or greater than 10, the discount is 15%.

To make the code more robust, you can use another else if instead of the else branch like this:

In this example, only when the number of items is greater than 10, the discount is 15%. The statement in the second else if branch executes.

If the number of items is less than zero, the statement in the else branch executes.

  • Use the if statement to execute code based on a condition.
  • Use the else branch if you want to execute code when the condition is false. It’s good practice to use the ternary operator ?: instead of a simple if…else statement.
  • Use if else if...else statement to execute code based on multiple conditions.

TypeScript - if else

An if statement can include one or more expressions which return boolean. If the boolean expression evaluates to true, a set of statements is then executed.

The following example includes multiple boolean expressions in the if condition.

In the above example, the if condition expression x < y is evaluated to true and so it executes the statement within the curly { } brackets.

if else Condition

An if else condition includes two blocks - if block and an else block. If the if condition evaluates to true, then the if block is executed. Otherwies, the else block is executed.

In the above example, the else block will be executed. Remember: else cannot include any condition and it must follow if or else if conditions.

The else if statement can be used after the if statement.

Ternary operator

A ternary operator is denoted by '?' and is used as a short cut for an if..else statement. It checks for a boolean condition and executes one of the two statements, depending on the result of the boolean condition.

In the above example, condition x > y is turned out be to false, so the second statement will be executed.

typescript if assignment

We are a team of passionate developers, educators, and technology enthusiasts who, with their combined expertise and experience, create in -depth, comprehensive, and easy to understand tutorials.We focus on a blend of theoretical explanations and practical examples to encourages hands - on learning. Visit About Us page for more information.

Advisory boards aren’t only for executives. Join the LogRocket Content Advisory Board today →

LogRocket blog logo

  • Product Management
  • Solve User-Reported Issues
  • Find Issues Faster
  • Optimize Conversion and Adoption
  • Start Monitoring for Free

The guide to conditional types in TypeScript

typescript if assignment

Since version 2.8, TypeScript has introduced support for conditional types. They might be a niche feature, but, as we’ll see, they are a very useful addition that helps us write reusable code.

Conditional types TypeScript

In this article, we’re going to see what conditional types are and why we might have used them intensively, even without knowing it.

Constraints on conditional types

Type inference in conditional types, distributive conditional types, nonnullable<t>, extract<t, u> and exclude<t, u>, parameters<t> and returntype<t>, constructorparameters<t> and instancetype<t>, what are conditional types.

Conditional types let us deterministically define type transformations depending on a condition. In brief, they are a ternary conditional operator applied at the type level rather than at the value level.

Conditional types are defined as follows:

In plain English, the definition above would be as follows:

If a given type SomeType extends another given type OtherType , then ConditionalType is TrueType , otherwise it is FalseType .

As usual, extends here means that any value of type SomeType is also of type OtherType .

Conditional types can be recursive; that is, one, or both, of the branches can themselves be a conditional type:

One of the main advantages of conditional types is their ability to narrow down the possible actual types of a generic type.

For instance, let’s assume we want to define ExtractIdType<T> , to extract, from a generic T , the type of a property named id . In this case, the actual generic type T must have a property named id . At first, we might come up with something like the following snippet of code:

Here, we made it explicit that T must have a property named id , with type either string or number . Then, we defined three interfaces: NumericId , StringId , and BooleanId .

If we attempt to extract the type of the id property, TypeScript correctly returns string and number for StringId and NumericId , respectively. However, it fails for BooleanId : Type 'BooleanId' does not satisfy the constraint '{ id: string | number; }'. Types of property 'id' are incompatible. Type 'boolean' is not assignable to type 'string | number' .

Still, how can we enhance our ExtractIdType to accept any type T and then resort to something like never if T did not define the required id property? We can do that using conditional types:

By simply moving the constraint in the conditional type, we were able to make the definition of BooleanIdType work. In this second version, TypeScript knows that if the first branch is true, then T will have a property named id with type string | number .

It is so common to use conditional types to apply constraints and extract properties’ types that we can use a sugared syntax for that. For instance, we could rewrite our definition of ExtractIdType as follows:

In this case, we refined the ExtractIdType type. Instead of forcing the type of the id property to be of type string | number, we’ve introduced a new type U using the infer keyword. Hence, BooleanIdType won’t evaluate to never anymore. In fact, TypeScript will extract boolean as expected.

infer provides us with a way to introduce a new generic type, instead of specifying how to retrieve the element type from the true branch.

At the end of the post, we’ll see some useful inbuilt types relying on the infer keyword.

In TypeScript, conditional types are distributive over union types. In other words, when evaluated against a union type, the conditional type applies to all the members of the union. Let’s see an example:

In the example above, we simply defined a conditional type named ToStringArray , evaluating to string[] if and only if its generic parameter is string . Otherwise, it evaluates to never .

typescript if assignment

Over 200k developers use LogRocket to create better digital experiences

typescript if assignment

Let’s now see how TypeScript evaluates ToStringArray<string | number> to define StringArray . First, ToStringArray distributes over the union:

Then, we can replace ToStringArray with its definition:

Evaluating the conditionals leaves us with the following definition:

Since never is a subtype of any type, we can remove it from the union:

Most of the times the distributive property of conditional types is desired. Nonetheless, to avoid it we can just enclose each side of the extends keyword with square brackets:

In this case, when evaluating StringArray , the definition of ToStringArray does not distribute anymore:

Hence, since string | number does not extend, string, StringArray will become never .

Lastly, the distributive property doesn’t hold if the union type is part of a larger expression (i.e., a function, object, or tuple), no matter if this larger expression appears before or after extends . Let’s see an example:

Inbuilt conditional types

This last section shows a few examples of conditional types defined by TypeScript’s standard library.

NonNullable<T> filters out the null and undefined values from a type T :

Extract<T, U> and are one the opposite of the other. The former filters the T type to keep all the types that are assignable to U . The latter, on the other hand, will keep the types that are not assignable to U :

In the example above when defining A , we asked TypeScript to filter out of string | string[] all the types that were not assignable to any[] . That would only be string, as string[] is perfectly assignable to any[] . On the contrary, when we defined B , we asked TypeScript to do just the opposite. As expected, the result is string, instead of string[] .

The same argument holds for C and D . In the definition of C , number is not assignable to boolean . Hence, TypeScript infers never as a type. When it comes to defining D , instead, TypeScript keeps number .

Parameters<T> and ReturnType<T> let us extract all the parameter types and the return type of a function type, respectively:

Parameters<T> is a bit complex in its declaration. It basically produces a tuple type with all the parameter types (or never if T is not a function).

In particular, (...args: infer P) => any indicates a function type where the actual type of all the parameters ( P ) gets inferred. Any function will be assignable to this, as there is no constraint on the type of the parameters, and the return type is any .

Similarly, ReturnType<T> extracts the return type of a function. In this case, we use any to indicate that the parameters can be of any type. Then, we infer the return type R .

ConstructorParameters<T> and InstanceType<T> are the same things as Parameters<T> and ReturnType<T> , applied to constructor function types rather than to function types:

In this article, we explored conditional types in TypeScript. We started from the basic definition and how to use it to enforce constraints. We then saw how type inference works and explored the workings of the distributivity property of union types . Lastly, we looked at some of the common utility conditional types defined by TypeScript: we analyzed their definitions and complemented them with a few examples.

As we saw throughout this article, conditional types are a very advanced feature of the type system. However, we’ll likely end up using them almost on a daily basis because TypeScript’s standard library widely employs them.

Hopefully, this post will help you write your own types to simplify your code and make it more readable and maintainable in the long run.

LogRocket : Full visibility into your web and mobile apps

LogRocket Dashboard Free Trial Banner

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page and mobile apps.

Try it for free .

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • #typescript

typescript if assignment

Stop guessing about your digital experience with LogRocket

Recent posts:.

Using Aoi Js To Build A Bot For Discord

Using aoi.js to build a bot on Discord

Explore how the aoi.js library makes it easy to create Discord bots with useful functionalities for frontend applications.

typescript if assignment

Web Components adoption guide: Overview, examples, and alternatives

Evaluate Web Components, a set of standards that allow you to create custom HTML tags for more reusable, manageable code.

typescript if assignment

Using AWS Lambda and CloudFront to optimize image handling

Leverage services like AWS Lambda, CloudFront, and S3 to handle images more effectively, optimizing performance and providing a better UX.

typescript if assignment

Building web-based terminal components with Termino.js

Explore Termino.js, an open source library for integrating web-based terminals into applications, in this introduction article.

typescript if assignment

2 Replies to "The guide to conditional types in TypeScript"

Nice article. In the example of section “Type inference in conditional types”, `T[“I’d”]` should be `U` I think.

Yes, you’re right. Both actually work, but `U` is more correct, considering that the example shows the purpose of the `infer` keyword.

Leave a Reply Cancel reply

  • Course List
  • Introduction to TypeScript
  • Environment Setup
  • Workspace & first app
  • Basic Syntax
  • Variables & Constants
  • Conditional Control
  • if, else if, else & switch
  • Iteration Control
  • for, while, do-while loops
  • Intermediate
  • Map Collections
  • Object Oriented Programming
  • OOP: Classes & Objects
  • OOP: Standalone Objects
  • OOP: Constructors
  • OOP: Property Modifiers
  • OOP: Access Modifiers
  • OOP: Parameter Properties
  • OOP: Getters & Setters
  • OOP: Static methods
  • OOP: Index Signatures
  • OOP: Inheritance
  • OOP: Composition
  • Compilation Config (tsconfig.json)

TypeScript if, else & switch Conditional Control Tutorial

In this TypeScript tutorial we learn to control the flow of our application through the if, else if, else and switch statements.

We also learn how to nest conditional statements inside one another, and use the shorthand method of writing an if statement with the ternary operator.

  • What is conditional control
  • The if statement
  • The else if ladder
  • The else fallback
  • Nesting if statements
  • The ternary operator ( ? : )
  • The switch statement

Summary: Points to remember

We can control the flow of our application by evaluating certain conditions. Based on the result of the evaluation, we can then execute certain sections of code.

As an example, let’s consider an application with a member area. To gain access to the member area, a user must provide the correct login credentials.

If the user provides the correct credentials, they are allowed to enter the member area. If not, they are given the option to try again or reset their password.

In pseudocode, the example above would look something like this.

The actual code will not look like the example above, but it serves to give you an example of what conditional control is used for.

We can use conditional control in TypeScript through the following statements, in combination with comparison and logical operators.

The if statement will evaluate if a condition is true or not.

If a condition proves true, the compiler will execute the code in the if statement’s code block. If the condition proves false, the compiler will move on to the next statement outside and below the code block.

An if statement is written with the keyword if , followed by the condition(s) we want to evaluate between parentheses.

Then, we specify a code block with open and close curly braces that will be executed if the condition proves true.

In the example above, the if statement compares the two numbers to see if they are the same. Because they are, the message is printed to the console.

If we change one of the numbers to another value, the condition will be false and the message will not be printed.

When we run the example above, nothing is printed to the console because the condition is false and the print statement never gets executed.

The else if ladder can be used when we want to evaluate extra conditions that relate to our if statement.

To create an else if ladder, we simply add the keyword else between two if statements, connecting them.

If the first condition proves false, the compiler will evaluate the second before moving on to any other code.

We use else if ladders to connect our if statements together, sort of grouping them.

note An else if statement can only follow an if statement, it cannot stand on its own. The first conditional statement must always be an if.

The else statement acts as a catch-all fallback for anything that isn’t covered by an if statement or an else if ladder.

The else statement doesn’t need a conditional block in the header because it works as a catch-all. We only write the keyword else , followed by its execution block.

note Like with the else if ladder, the else statement cannot stand on its own. It must follow an if statement or an else if ladder.

In the example above, our else execution block is executed because both if statements prove false.

TypeScript allows us to nest if statements inside other if statements. The compiler will evaluate each if statement in a hierarchical fashion.

All we do is write an if statement inside the execution block of another if statement.

We’re not limited to one nested if statement. We can have as many nested if conditions as we need in one control structure set.

note We recommend not nesting more than three levels deep. Nesting too deep is a bad practice, in most situations we can use an alternative method.

When we have an if else statement with only single execution statements, we can use what’s known as the ternary operator as a shorthand method to write it.

To use the ternary operator, we write the condition between parentheses first, followed by a ? (question mark) operator.

Then, we write the single execution statement if the condition proves true, followed by the : (colon) operator.

Finally, we write the single execution statement if the condition proves false, and terminate the whole expression with a semicolon.

Let’s consider the following if else statement.

In the example above, we evaluate if a number is 10 or not, and print a message to the console. Let’s convert this into shorthand with the ternary operator.

It may seem confusing at first, especially if you’ve only been writing traditional if statements for a while, but with practice it becomes second nature.

note It’s important to note that many developers do not like to use the ternary operator because it makes the code harder to read, especially for new developers.

It can also result in some impenetrably complex expressions. Some employers even disallow its use altogether.

For this reason, we’ll only be using traditional if else statements throughout this tutorial course, but feel free to practice the ternary in case you come across it in the wild.

We use the switch statement when we want to compare a single value against a list of many other values.

Before we explain how it works, let’s look at the syntax first.

First, we specify the main value that we will be comparing other values against. Then, in the code block, we specify our cases.

A case consists of the value we want to compare against the main value, and execution code after the : (colon) if the comparison proves true.

The break keyword tells the compiler that we’ve found what we’re looking for in the switch, so it can break out of it and continue on to code outside and below the switch.

The default case acts as our fallback statement, much like an else statement. In fact, the switch statement above is comparable to the following if statement.

Let’s see a real world example.

In the example above, we have a single main value (grade) that’s being evaluated against multiple cases. When a case evaluates to true, the execution statement after the colon executes.

note Typically a switch statement is only used when we want to compare one value to many others.

  • We control the flow of our application with if , else if , else and switch conditional control statements.
  • The else if ladder and else statement cannot stand on their own, they must be part of an if statement.
  • The else statement represents everything that the if and else if statements do not cover.
  • We can nest conditionals by writing them inside the execution blocks of other conditionals.
  • The ternary operator is a shorthand method of writing an if else statement with only a single execution statement.
  • A switch statement is used to compare one value against many.

TypeScript Topics

Typescript else if.

Switch to English

Table of Contents

Basic Syntax

How it works, example of typescript else if, order of conditions, don't forget the else clause, using assignment instead of comparison, using else if without an if statement.

## Introduction In the world of programming, decision making is a fundamental concept for building logic in an application. To create dynamic behavior in our code, we often need to choose between different courses of action based on certain conditions. This is where control flow statements like `if`, `else if` and `else` come into play. In TypeScript, an `else if` statement is a continuation of an `if` statement. It allows the programmer to include additional conditions that will be checked if the previous conditions are not met. It enables us to create complex logical constructs in a clean and efficient manner. ## Understanding TypeScript Else If

  • The basic syntax of `else if` in TypeScript is: if (condition1) { // block of code to be executed if condition1 is true } else if (condition2) { // block of code to be executed if the condition1 is false and condition2 is true } else { // block of code to be executed if the condition1 is false and condition2 is false }
  • When an `if else` statement is encountered, TypeScript starts by evaluating the condition1. If it's true, TypeScript executes the block of code associated with it and then skips the rest of the `if else` statement. If condition1 is false, TypeScript then moves on to evaluate condition2. If condition2 is true, then the corresponding block of code is executed. If neither condition1 nor condition2 are true, the block of code within the `else` clause is executed.
  • Let's examine a simple example of `else if` in TypeScript: let time = 18; if (time < 12) { console.log("Good morning!"); } else if (time < 18) { console.log("Good afternoon!"); } else { console.log("Good evening!"); } In this example, TypeScript checks whether the time is less than 12. If true, it logs "Good morning!" to the console. If false, it checks whether the time is less than 18. If that's true, it logs "Good afternoon!". If both conditions are false (i.e., the time is 18 or more), it logs "Good evening!".
  • The order of conditions in an `else if` statement is of crucial importance. TypeScript checks conditions from top to bottom. Once it finds a condition that is true, it executes the associated block of code and skips the rest. Therefore, you should always put more specific conditions before more general ones.
  • Although the `else` clause is optional in TypeScript, it's a good practice to always include it. The `else` clause serves as a catch-all for cases when none of the conditions in `if` and `else if` are true. Without the `else` clause, your program might behave unexpectedly in such cases.
  • A common mistake is using the assignment operator (`=`) instead of the equality operator (`==` or `===`) in conditions. This can lead to unexpected behavior because the assignment operator changes the value of a variable, while the equality operator tests whether two values are equal. let age = 20; if (age = 30) { console.log("You are 30 years old."); } else { console.log("You are not 30 years old."); } This code will always print "You are 30 years old.", even though the age variable is 20. This is because the assignment `age = 30` changes the age to 30 and then evaluates to true.
  • An `else if` statement must always follow an `if` or another `else if` statement. Using `else if` without an `if` statement will result in a syntax error. else if (age < 30) { console.log("You are less than 30 years old."); } This code will cause a syntax error because there's no `if` statement before the `else if` statement.

Popular Articles

  • Typescript Unknown Vs Any (Dec 06, 2023)
  • Typescript Undefined (Dec 06, 2023)
  • Typescript Type Definition (Dec 06, 2023)
  • Typescript Splice (Dec 06, 2023)
  • Typescript Return Type Of Function (Dec 06, 2023)

Lemborco

TypeScript if-else Condition

Back to: TypeScript Tutorial

TypeScript is a strongly typed superset of JavaScript that adds optional static typing, classes, and interfaces. It is a popular choice among developers for building complex web applications because it helps to catch errors at compile-time rather than run-time. In this lesson, we will focus on the best readable style for writing if-else conditions in TypeScript.

The basic syntax for if-else conditions in TypeScript is the same as in JavaScript:

To make if-else conditions more readable in TypeScript, we can follow some best practices:

  • Use meaningful variable and function names: Use descriptive names for variables and functions so that it is easier to understand what they represent. For example, instead of using x as a variable name, use something more meaningful like age or count .
  • Use type guards for type checking: Use type guards to check if a variable has a certain type before performing an operation on it. This can help avoid runtime errors. For example: interface Person { name: string; age: number; } function greet(person: Person | null) { if (person === null) { console.log("Hello, stranger!"); } else { console.log(`Hello, ${person.name}!`); } }

In conclusion, writing readable if-else conditions in TypeScript involves using meaningful variable and function names, avoiding nesting, using the ternary operator for simple conditions, and using type guards for type checking. By following these best practices, your code will be easier to understand and maintain.

Related posts:

  • Working with Files and Streams
  • Interfaces in TypeScript
  • Convert Existing JavaScript to TypeScript Project
  • What is Type Assertion in TypeScript?
  • What is Type Inference in TypeScript?
  • What is Type Annotation in TypeScript?
  • Install TypeScript and Setup Dev Environment
  • What is TypeScript?
  • C# flow control
  • C# operator

Marius Schulz

Nullish Coalescing: The ?? Operator in TypeScript

TypeScript 3.7 added support for the ?? operator, which is known as the nullish coalescing operator . We can use this operator to provide a fallback value for a value that might be null or undefined .

# Truthy and Falsy Values in JavaScript

Before we dive into the ?? operator, let's recall that JavaScript values can either be truthy or falsy : when coerced to a Boolean, a value can either produce the value true or false . In JavaScript, the following values are considered to be falsy:

All other JavaScript values will produce the value true when coerced to a Boolean and are thus considered truthy.

# Providing Fallback Values with the ?? Operator

The ?? operator can be used to provide a fallback value in case another value is null or undefined . It takes two operands and is written like this:

If the left operand is null or undefined , the ?? expression evaluates to the right operand:

Otherwise, the ?? expression evaluates to the left operand:

Notice that all left operands above are falsy values. If we had used the || operator instead of the ?? operator, all of these expressions would've evaluated to their respective right operands:

This behavior is why you shouldn't use the || operator to provide a fallback value for a nullable value. For falsy values, the result might not be the one you wanted or expected. Consider this example:

The expression options.prettyPrint ?? true lets us provide the default value true in case that the prettyPrint property contains the value null or undefined . If prettyPrint contains the value false , the expression false ?? true still evaluates to false , which is exactly the behavior we want here.

Note that using the || operator here would lead to incorrect results. options.prettyPrint || true would evaluate to true for the values null and undefined , but also for the value false . This would clearly not be intended. I've seen this happen in practice a handful of times, so make sure to keep this case in mind and use towards the ?? operator instead.

# Compiled Output: ES2020 and Newer

The nullish coalescing operator has reached Stage 4 ("Finished") of the TC39 process and is now officially part of ES2020 . Therefore, the TypeScript compiler will emit the ?? operator as is without any downleveling when you're targeting "ES2020" (or a newer language version) or "ESNext" in your tsconfig.json file:

So, this simple expression will be emitted unchanged:

If you're planning on using the ?? operator while targeting "ES2020" or a newer language version, head over to caniuse.com and node.green and make sure that all the JavaScript engines you need to support have implemented the operator.

# Compiled JavaScript Output: ES2019 and Older

If you're targeting "ES2019" or an older language version in your tsconfig.json file, the TypeScript compiler will rewrite the nullish coalescing operator into a conditional expression. That way, we can start using the ?? operator in our code today and still have the compiled code successfully parse and execute in older JavaScript engines.

Let's look at the same simple ?? expression again:

Assuming we're targeting "ES2019" or a lower language version, the TypeScript compiler will emit the following JavaScript code:

The value variable is compared against both null and undefined (the result of the expression void 0 ). If both comparisons produce the value false , the entire expression evaluates to value ; otherwise, it evaluates to fallbackValue .

Now, let's look at a slightly more complex example. Instead of a simple value variable, we're going to use a getValue() call expression as the left operand of the ?? operator:

In this case, the compiler will emit the following JavaScript code (modulo whitespace differences):

You can see that the compiler generated an intermediate variable _a to store the return value of the getValue() call. The _a variable is then compared against null and void 0 and (potentially) used as the resulting value of the entire expression. This intermediate variable is necessary so that the getValue function is only called once.

# Compiled Output: Checking for null and undefined

You might be wondering why the compiler emits the following expression to check the value variable against null and undefined :

Couldn't the compiler emit the following shorter check instead?

Unfortunately, it can't do that without sacrificing correctness. For almost all values in JavaScript, the comparison value == null is equivalent to value === null || value === undefined . For those values, the negation value != null is equivalent to value !== null && value !== undefined . However, there is one value for which these two checks aren't equivalent, and that value is document.all :

The value document.all is not considered to be strictly equal to either null or undefined , but it is considered to be loosely equal to both null and undefined . Because of this anomaly, the TypeScript compiler can't emit value != null as a check because it would produce incorrect results for document.all .

You can read more about this curious behavior in an answer to the Why is document.all falsy? question on Stack Overflow. Oh, the things we do for web compatibility.

This article and 44 others are part of the TypeScript Evolution series. Have a look!

  • Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • English (US)

Nullish coalescing assignment (??=)

The nullish coalescing assignment ( ??= ) operator, also known as the logical nullish assignment operator, only evaluates the right operand and assigns to the left if the left operand is nullish ( null or undefined ).

Description

Nullish coalescing assignment short-circuits , meaning that x ??= y is equivalent to x ?? (x = y) , except that the expression x is only evaluated once.

No assignment is performed if the left-hand side is not nullish, due to short-circuiting of the nullish coalescing operator. For example, the following does not throw an error, despite x being const :

Neither would the following trigger the setter:

In fact, if x is not nullish, y is not evaluated at all.

Using nullish coalescing assignment

You can use the nullish coalescing assignment operator to apply default values to object properties. Compared to using destructuring and default values , ??= also applies the default value if the property has value null .

Specifications

Browser compatibility.

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

  • Nullish coalescing operator ( ?? )

TypeScript ESLint: Unsafe assignment of an any value [Fix]

avatar

Last updated: Feb 29, 2024 Reading time · 5 min

banner

# TypeScript ESLint: Unsafe assignment of an any value

The error "@typescript-eslint/no-unsafe-assignment: Unsafe assignment of an any value." occurs when you assign a value with a type of any to a variable or a property.

To solve the error, set the variable to a specific type or disable the ESLint rule.

Here are some examples of when the ESLint error is raised.

All of the assignments above cause the error because the ESLint rule prevents you from assigning a value with an any type to a variable.

The any type effectively turns off type checking and should be used sparingly.

This article addresses 2 similar ESLint errors:

  • @typescript-eslint/no-unsafe-assignment: Unsafe assignment of an any value.
  • Unexpected any. Specify a different type. eslint@typescript-eslint/no-explicit-any

# Disabling the @typescript-eslint/no-unsafe-assignment ESLint rule

One way to get around the ESLint error is to disable the rule.

For example, the following comment disables the rule for 1 line.

disabling the ts eslint no unsafe assignment rule

If you need to disable the @typescript-eslint/no-explicit-any rule for a single line, use the following comment.

If you need to disable multiple rules for a line, separate them by a comma.

If you need to disable the rule for the entire file, use the following comment.

If you need to disable the @typescript-eslint/no-explicit-any rule for the entire file, use the following comment instead.

You can disable both rules for the entire file by using the following comment.

If you want to disable the rules globally, add the following 2 rules to your .eslintrc.js file.

disable the two rules

If you use a .eslintrc.json file, make sure to double-quote the keys and values.

# Setting the variable or property to unknown instead of any

Alternatively, you can set the variable or property to unknown to resolve the ESLint error.

setting the variable property to unknown instead of any

The unknown type is the type-safe counterpart of any .

When working with the unknown type, we basically tell TypeScript that we're going to get this value, but we don't know its type.

We are going to check with a couple of if statements to track the type down and use it safely.

I have written a detailed guide on how to check the type of a variable in TypeScript .

When using the unknown type, you have to use an if statement as a type guard to check the type of the variable before you are able to use any type-specific methods (e.g. string, array, object, etc).

# The error commonly occurs when parsing a JSON string

The error commonly occurs when parsing a JSON string with the JSON.parse() method.

The result variable stores a value of any type because TypeScript doesn't know the type of the value that is being parsed.

One way to resolve the issue is to use a type predicate .

using type predicate to solve the error

The value is Employee syntax is called a type predicate.

Our function basically checks if the passed-in value is compatible with an object of type Employee .

Notice that in the if block in which we called the isAnEmployee() function, the parsed variable is typed as Employee and we can access the id and name properties without getting TypeScript or ESLint errors.

I've written a detailed guide on how to check if a value is an object .

# Resolve the issue by typing the variable explicitly

You can also resolve the issue by typing the variable explicitly and removing the any type.

Here is an example of typing an object.

And here is an example of typing an array of objects.

You might have to use a type assertion, e.g. when parsing a JSON string.

In some rare cases, you might have to widen the type to unknown before using a type assertion to set a more specific type.

I've written detailed guides on:

  • How to initialize a typed Empty Object in TypeScript
  • Declare an Empty Array for a typed Variable in TypeScript
  • How to add Elements to an Array in TypeScript
  • Check if an Array contains a Value in TypeScript
  • Check if a Value is an Array (of type) in TypeScript
  • How to declare an Array of Objects in TypeScript
  • How to declare a Two-dimensional Array in TypeScript
  • Declare Array of Numbers, Strings or Booleans in TypeScript
  • Create an Object based on an Interface in TypeScript
  • Create a Type from an object's Keys or Values in TypeScript
  • ESLint: Expected property shorthand object-shorthand [Fixed]
  • 'X' should be listed in the project's dependencies, not devDependencies
  • ESLint: Unexpected lexical declaration in case block [Fixed]
  • ESLint couldn't find the config 'prettier' to extend from
  • Import in body of module reorder to top eslint import/first
  • ESLint: A form label must be associated with a control

book cover

Borislav Hadzhiev

Web Developer

buy me a coffee

Copyright © 2024 Borislav Hadzhiev

IMAGES

  1. if else

    typescript if assignment

  2. A beginner’s guide to TypeScript (with some history of the TypeScript

    typescript if assignment

  3. Typescript if, else & nested if statement

    typescript if assignment

  4. TypeScript Function Types: A Beginner's Guide

    typescript if assignment

  5. TypeScript if

    typescript if assignment

  6. #4 TypeScript Tutorial for Beginners

    typescript if assignment

VIDEO

  1. Typescript Assignment-3-Type a simple message on screen

  2. Typescript Q no 8 solved

  3. Typescript

  4. JavaScript

  5. Use Destructuring Assignment to Pass an Object as a Function's Parameters (ES6) freeCodeCamp

  6. Typescript 45 Questions Assignment Part 14

COMMENTS

  1. TypeScript: Documentation

    Conditional Types. At the heart of most useful programs, we have to make decisions based on input. JavaScript programs are no different, but given the fact that values can be easily introspected, those decisions are also based on the types of the inputs. Conditional types help describe the relation between the types of inputs and outputs.

  2. Best Way for Conditional Variable Assignment

    There are two methods I know of that you can declare a variable's value by conditions. Method 1: If the condition evaluates to true, the value on the left side of the column would be assigned to the variable. If the condition evaluates to false the condition on the right will be assigned to the variable. You can also nest many conditions into ...

  3. TypeScript if...else Statement

    Summary: in this tutorial, you will learn about the TypeScript if...else statement. TypeScript if statement. An if statement executes a statement based on a condition. If the condition is truthy, the if statement will execute the statements inside its body:

  4. TypeScript if else

    In the above example, the if condition expression x < y is evaluated to true and so it executes the statement within the curly { } brackets.. if else Condition. An if else condition includes two blocks - if block and an else block. If the if condition evaluates to true, then the if block is executed. Otherwies, the else block is executed.

  5. The guide to conditional types in TypeScript

    On the contrary, when we defined B, we asked TypeScript to do just the opposite. As expected, the result is string, instead of string[]. The same argument holds for C and D. In the definition of C, number is not assignable to boolean. Hence, TypeScript infers never as a type. When it comes to defining D, instead, TypeScript keeps number.

  6. Understanding TypeScript If Statement

    What is the TypeScript If Statement? The TypeScript If statement is a powerful control flow statement that lets you execute a block of code only when a specified condition is true. It's a crucial part of TypeScript as it allows the program to make decisions and execute statements based on those decisions. Syntax of the TypeScript If Statement

  7. TypeScript if, else & switch Conditional Control Tutorial

    In this TypeScript tutorial we learn to control the flow of our application through the if, else if, else and switch statements. We also learn how to nest conditional statements inside one another, and use the shorthand method of writing an if statement with the ternary operator. What is conditional control. The if statement.

  8. Understanding TypeScript Else If Statement

    The article provides an in-depth understanding of TypeScript's 'else if' statement, its syntax, working, examples, and common pitfalls. A must-read for both beginners and experienced TypeScript developers. ... This is because the assignment `age = 30` changes the age to 30 and then evaluates to true. Using Else If Without an If Statement;

  9. TypeScript if-else Condition

    TypeScript is a strongly typed superset of JavaScript that adds optional static typing, classes, and interfaces. It is a popular choice among developers for building complex web applications because it helps to catch errors at compile-time rather than run-time. In this lesson, we will focus on the best readable style for writing if-else ...

  10. Set a default value if Null or Undefined in TypeScript

    You can also use the logical OR (||) operator to provide a default value if a variable is null or undefined. index.ts. const role: string | null = null; const result = role || 'designer'; console.log(result); The code for this article is available on GitHub. The logical OR (||) operator returns the value to the right if the value to the left is ...

  11. Assign variable in if condition statement, good practice or not?

    Assignment in a conditional statement is valid in javascript, because your just asking "if assignment is valid, do something which possibly includes the result of the assignment". But indeed, assigning before the conditional is also valid, not too verbose, and more commonly used. - okdewit.

  12. Nullish Coalescing: The ?? Operator in TypeScript

    Nullish Coalescing: The ?? Operator in TypeScript August 6, 2020. TypeScript 3.7 added support for the ?? operator, which is known as the nullish coalescing operator.We can use this operator to provide a fallback value for a value that might be null or undefined. #Truthy and Falsy Values in JavaScript Before we dive into the ?? operator, let's recall that JavaScript values can either be truthy ...

  13. Nullish coalescing assignment (??=)

    No assignment is performed if the left-hand side is not nullish, due to short-circuiting of the nullish coalescing operator. For example, the following does not throw an error, despite x being const :

  14. Ternary Conditional Operator Typescript

    Logical Operators. The Typescript conditional operator is a Ternary Operator, which takes three operands. The first operand is a condition to evaluate. It is followed by a question mark (? ), then an expression ( expression1 ). It is then followed by a colon (:) and second expression ( expression2 ). If the condition is true, then expression1 ...

  15. Best practice for defining a variable on a condition in Typescript

    603 9 25. The best practice when you have to define a variable on a condition is to use a ternary operator. This will ensure that the variable is always of the correct type. If there are more than two cases, you can use a switch statement. However, you should always check if the variable is undefined before using it.

  16. TypeScript ESLint: Unsafe assignment of an any value [Fix]

    Our function basically checks if the passed-in value is compatible with an object of type Employee.. Notice that in the if block in which we called the isAnEmployee() function, the parsed variable is typed as Employee and we can access the id and name properties without getting TypeScript or ESLint errors.. I've written a detailed guide on how to check if a value is an object.

  17. Assignment Operators in TypeScript

    An assignment operators requires two operands. The value of the right operand is assigned to the left operand. The sign = denotes the simple assignment operator. The typescript also has several compound assignment operators, which is actually shorthand for other operators. List of all such operators are listed below

  18. typescript

    Here is one way to do it by passing an object with both parameters. By using a type that has true and the one signature or false and the other, the compiler can differentiate the object by testing the b property. type f = { b: false, t: (f: string) => void }; type t = { b: true, t: (f: string[]) => void }; type fOrT = f | t;

  19. Use if else to declare a `let` or `const` to use after the if/else?

    Alternatively, just declare it outside of the if block, which allows you to get rid of the duplication as well: classes += ` ${styles.circularBorder}`; // or if you care about the order, // classes = `${styles.circularBorder} ${classes}`; Also have a look at messy classnames construction.