• DSA with JS - Self Paced
  • JS Tutorial
  • JS Exercise
  • JS Interview Questions
  • JS Operator
  • JS Projects
  • JS Examples
  • JS Free JS Course
  • JS A to Z Guide
  • JS Formatter

TypeScript Operators

  • Typescript Keyof Type Operator
  • TypeScript Constraints
  • TypeScript Instanceof Operator
  • TypeScript Object
  • TypeScript Tuples
  • TypeScript Arrays
  • TypeScript Numbers
  • TypeScript Literal Types
  • TypeScript class
  • TypeScript Optional Parameters
  • TypeScript Tutorial
  • TypeScript Map
  • TypeScript Object Types
  • TypeScript Mapped Types
  • TypeScript Assertions Type
  • Rest Parameters in TypeScript
  • Interfaces in TypeScript
  • TypeScript Generic Types
  • Next.js TypeScript
  • TypeScript in operator narrowing Type
  • TypeScript Function
  • TypeScript Construct Signatures
  • TypeScript Array some() Method
  • TypeScript any Type
  • How to use Spread Operator in TypeScript ?
  • TypeScript Rest Arguments
  • How to install TypeScript ?
  • TypeScript Array reverse() Method
  • TypeScript | Array sort() Method

TypeScript operators are symbols or keywords that perform operations on one or more operands. In this article, we are going to learn various types of TypeScript Operators.

Below are the different TypeScript Operators:

Table of Content

TypeScript Arithmetic operators

Typescript logical operators, typescript relational operators, typescript bitwise operators, typescript assignment operators, typescript ternary/conditional operator, typescript type operators, typescript string operators.

In TypeScript, arithmetic operators are used to perform mathematical calculations.

In TypeScript, logical operators are used to perform logical operations on Boolean values.

In TypeScript, relational operators are used to compare two values and determine the relationship between them.

In TypeScript, bitwise operators perform operations on the binary representation of numeric values.

In TypeScript, assignment operators are used to assign values to variables and modify their values based on arithmetic or bitwise operations.

In TypeScript, the ternary operator, also known as the conditional operator, is a concise way to write conditional statements. It allows you to express a simple if-else statement in a single line.

In TypeScript, type operators are constructs that allow you to perform operations on types. These operators provide powerful mechanisms for defining and manipulating types in a flexible and expressive manner.

In TypeScript, string operators and features are used for manipulating and working with string values.

Please Login to comment...

Similar reads.

  • Web Technologies

advertisewithusBannerImg

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

This page has been deprecated

This handbook page has been replaced, go to the new page

Advanced Types

This page lists some of the more advanced ways in which you can model types, it works in tandem with the Utility Types doc which includes types which are included in TypeScript and available globally.

Type Guards and Differentiating Types

Union types are useful for modeling situations when values can overlap in the types they can take on. What happens when we need to know specifically whether we have a Fish ? A common idiom in JavaScript to differentiate between two possible values is to check for the presence of a member. As we mentioned, you can only access members that are guaranteed to be in all the constituents of a union type.

To get the same code working via property accessors, we’ll need to use a type assertion:

This isn’t the sort of code you would want in your codebase however.

User-Defined Type Guards

It would be much better if once we performed the check, we could know the type of pet within each branch.

It just so happens that TypeScript has something called a type guard . A type guard is some expression that performs a runtime check that guarantees the type in some scope.

Using type predicates

To define a type guard, we simply need to define a function whose return type is a type predicate :

pet is Fish is our type predicate in this example. A predicate takes the form parameterName is Type , where parameterName must be the name of a parameter from the current function signature.

Any time isFish is called with some variable, TypeScript will narrow that variable to that specific type if the original type is compatible.

Notice that TypeScript not only knows that pet is a Fish in the if branch; it also knows that in the else branch, you don’t have a Fish , so you must have a Bird .

You may use the type guard isFish to filter an array of Fish | Bird and obtain an array of Fish :

Using the in operator

The in operator also acts as a narrowing expression for types.

For a n in x expression, where n is a string literal or string literal type and x is a union type, the “true” branch narrows to types which have an optional or required property n , and the “false” branch narrows to types which have an optional or missing property n .

typeof type guards

Let’s go back and write the code for a version of padLeft which uses union types. We could write it with type predicates as follows:

However, having to define a function to figure out if a type is a primitive is kind of a pain. Luckily, you don’t need to abstract typeof x === "number" into its own function because TypeScript will recognize it as a type guard on its own. That means we could just write these checks inline.

These typeof type guards are recognized in two different forms: typeof v === "typename" and typeof v !== "typename" , where "typename" can be one of typeof operator’s return values ( "undefined" , "number" , "string" , "boolean" , "bigint" , "symbol" , "object" , or "function" ). While TypeScript won’t stop you from comparing to other strings, the language won’t recognize those expressions as type guards.

instanceof type guards

If you’ve read about typeof type guards and are familiar with the instanceof operator in JavaScript, you probably have some idea of what this section is about.

instanceof type guards are a way of narrowing types using their constructor function. For instance, let’s borrow our industrial strength string-padder example from earlier:

The right side of the instanceof needs to be a constructor function, and TypeScript will narrow down to:

  • the type of the function’s prototype property if its type is not any
  • the union of types returned by that type’s construct signatures

in that order.

Nullable types

TypeScript has two special types, null and undefined , that have the values null and undefined respectively. We mentioned these briefly in the Basic Types section .

By default, the type checker considers null and undefined assignable to anything. Effectively, null and undefined are valid values of every type. That means it’s not possible to stop them from being assigned to any type, even when you would like to prevent it. The inventor of null , Tony Hoare, calls this his “billion dollar mistake” .

The strictNullChecks flag fixes this: when you declare a variable, it doesn’t automatically include null or undefined . You can include them explicitly using a union type:

Note that TypeScript treats null and undefined differently in order to match JavaScript semantics. string | null is a different type than string | undefined and string | undefined | null .

From TypeScript 3.7 and onwards, you can use optional chaining to simplify working with nullable types.

Optional parameters and properties

With strictNullChecks , an optional parameter automatically adds | undefined :

The same is true for optional properties:

Type guards and type assertions

Since nullable types are implemented with a union, you need to use a type guard to get rid of the null . Fortunately, this is the same code you’d write in JavaScript:

The null elimination is pretty obvious here, but you can use terser operators too:

In cases where the compiler can’t eliminate null or undefined , you can use the type assertion operator to manually remove them. The syntax is postfix ! : identifier! removes null and undefined from the type of identifier :

Type Aliases

Type aliases create a new name for a type. Type aliases are sometimes similar to interfaces, but can name primitives, unions, tuples, and any other types that you’d otherwise have to write by hand.

Aliasing doesn’t actually create a new type - it creates a new name to refer to that type. Aliasing a primitive is not terribly useful, though it can be used as a form of documentation.

Just like interfaces, type aliases can also be generic - we can just add type parameters and use them on the right side of the alias declaration:

We can also have a type alias refer to itself in a property:

Together with intersection types, we can make some pretty mind-bending types:

Interfaces vs. Type Aliases

As we mentioned, type aliases can act sort of like interfaces; however, there are some subtle differences.

Almost all features of an interface are available in type , the key distinction is that a type cannot be re-opened to add new properties vs an interface which is always extendable.

Because an interface more closely maps how JavaScript objects work by being open to extension , we recommend using an interface over a type alias when possible.

On the other hand, if you can’t express some shape with an interface and you need to use a union or tuple type, type aliases are usually the way to go.

Enum Member Types

As mentioned in our section on enums , enum members have types when every member is literal-initialized.

Much of the time when we talk about “singleton types”, we’re referring to both enum member types as well as numeric/string literal types, though many users will use “singleton types” and “literal types” interchangeably.

Polymorphic this types

A polymorphic this type represents a type that is the subtype of the containing class or interface. This is called F -bounded polymorphism, a lot of people know it as the fluent API pattern. This makes hierarchical fluent interfaces much easier to express, for example. Take a simple calculator that returns this after each operation:

Since the class uses this types, you can extend it and the new class can use the old methods with no changes.

Without this types, ScientificCalculator would not have been able to extend BasicCalculator and keep the fluent interface. multiply would have returned BasicCalculator , which doesn’t have the sin method. However, with this types, multiply returns this , which is ScientificCalculator here.

Index types

With index types, you can get the compiler to check code that uses dynamic property names. For example, a common JavaScript pattern is to pick a subset of properties from an object:

Here’s how you would write and use this function in TypeScript, using the index type query and indexed access operators:

The compiler checks that manufacturer and model are actually properties on Car . The example introduces a couple of new type operators. First is keyof T , the index type query operator . For any type T , keyof T is the union of known, public property names of T . For example:

keyof Car is completely interchangeable with "manufacturer" | "model" | "year" . The difference is that if you add another property to Car , say ownersAddress: string , then keyof Car will automatically update to be "manufacturer" | "model" | "year" | "ownersAddress" . And you can use keyof in generic contexts like pluck , where you can’t possibly know the property names ahead of time. That means the compiler will check that you pass the right set of property names to pluck :

The second operator is T[K] , the indexed access operator . Here, the type syntax reflects the expression syntax. That means that taxi["manufacturer"] has the type Car["manufacturer"] — which in our example is just string . However, just like index type queries, you can use T[K] in a generic context, which is where its real power comes to life. You just have to make sure that the type variable K extends keyof T . Here’s another example with a function named getProperty .

In getProperty , o: T and propertyName: K , so that means o[propertyName]: T[K] . Once you return the T[K] result, the compiler will instantiate the actual type of the key, so the return type of getProperty will vary according to which property you request.

Index types and index signatures

keyof and T[K] interact with index signatures. An index signature parameter type must be ‘string’ or ‘number’. If you have a type with a string index signature, keyof T will be string | number (and not just string , since in JavaScript you can access an object property either by using strings ( object["42"] ) or numbers ( object[42] )). And T[string] is just the type of the index signature:

If you have a type with a number index signature, keyof T will just be number .

Mapped types

A common task is to take an existing type and make each of its properties optional:

Or we might want a readonly version:

This happens often enough in JavaScript that TypeScript provides a way to create new types based on old types — mapped types . In a mapped type, the new type transforms each property in the old type in the same way. For example, you can make all properties optional or of a type readonly . Here are a couple of examples:

And to use it:

Note that this syntax describes a type rather than a member. If you want to add members, you can use an intersection type:

Let’s take a look at the simplest mapped type and its parts:

The syntax resembles the syntax for index signatures with a for .. in inside. There are three parts:

  • The type variable K , which gets bound to each property in turn.
  • The string literal union Keys , which contains the names of properties to iterate over.
  • The resulting type of the property.

In this simple example, Keys is a hard-coded list of property names and the property type is always boolean , so this mapped type is equivalent to writing:

Real applications, however, look like Readonly or Partial above. They’re based on some existing type, and they transform the properties in some way. That’s where keyof and indexed access types come in:

But it’s more useful to have a general version.

In these examples, the properties list is keyof T and the resulting type is some variant of T[P] . This is a good template for any general use of mapped types. That’s because this kind of transformation is homomorphic , which means that the mapping applies only to properties of T and no others. The compiler knows that it can copy all the existing property modifiers before adding any new ones. For example, if Person.name was readonly, Partial<Person>.name would be readonly and optional.

Here’s one more example, in which T[P] is wrapped in a Proxy<T> class:

Note that Readonly<T> and Partial<T> are so useful, they are included in TypeScript’s standard library along with Pick and Record :

Readonly , Partial and Pick are homomorphic whereas Record is not. One clue that Record is not homomorphic is that it doesn’t take an input type to copy properties from:

Non-homomorphic types are essentially creating new properties, so they can’t copy property modifiers from anywhere.

Note that keyof any represents the type of any value that can be used as an index to an object. In otherwords, keyof any is currently equal to string | number | symbol .

Inference from mapped types

Now that you know how to wrap the properties of a type, the next thing you’ll want to do is unwrap them. Fortunately, that’s pretty easy:

Note that this unwrapping inference only works on homomorphic mapped types. If the mapped type is not homomorphic you’ll have to give an explicit type parameter to your unwrapping function.

Conditional Types

A conditional type selects one of two possible types based on a condition expressed as a type relationship test:

The type above means when T is assignable to U the type is X , otherwise the type is Y .

A conditional type T extends U ? X : Y is either resolved to X or Y , or deferred because the condition depends on one or more type variables. When T or U contains type variables, whether to resolve to X or Y , or to defer, is determined by whether or not the type system has enough information to conclude that T is always assignable to U .

As an example of some types that are immediately resolved, we can take a look at the following example:

Another example would be the TypeName type alias, which uses nested conditional types:

But as an example of a place where conditional types are deferred - where they stick around instead of picking a branch - would be in the following:

In the above, the variable a has a conditional type that hasn’t yet chosen a branch. When another piece of code ends up calling foo , it will substitute in U with some other type, and TypeScript will re-evaluate the conditional type, deciding whether it can actually pick a branch.

In the meantime, we can assign a conditional type to any other target type as long as each branch of the conditional is assignable to that target. So in our example above we were able to assign U extends Foo ? string : number to string | number since no matter what the conditional evaluates to, it’s known to be either string or number .

Distributive conditional types

Conditional types in which the checked type is a naked type parameter are called distributive conditional types . Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of T extends U ? X : Y with the type argument A | B | C for T is resolved as (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y) .

In instantiations of a distributive conditional type T extends U ? X : Y , references to T within the conditional type are resolved to individual constituents of the union type (i.e. T refers to the individual constituents after the conditional type is distributed over the union type). Furthermore, references to T within X have an additional type parameter constraint U (i.e. T is considered assignable to U within X ).

Notice that T has the additional constraint any[] within the true branch of Boxed<T> and it is therefore possible to refer to the element type of the array as T[number] . Also, notice how the conditional type is distributed over the union type in the last example.

The distributive property of conditional types can conveniently be used to filter union types:

Conditional types are particularly useful when combined with mapped types:

Note, conditional types are not permitted to reference themselves recursively. For example the following is an error.

Type inference in conditional types

Within the extends clause of a conditional type, it is now possible to have infer declarations that introduce a type variable to be inferred. Such inferred type variables may be referenced in the true branch of the conditional type. It is possible to have multiple infer locations for the same type variable.

For example, the following extracts the return type of a function type:

Conditional types can be nested to form a sequence of pattern matches that are evaluated in order:

The following example demonstrates how multiple candidates for the same type variable in co-variant positions causes a union type to be inferred:

Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred:

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.

It is not possible to use infer declarations in constraint clauses for regular type parameters:

However, much the same effect can be obtained by erasing the type variables in the constraint and instead specifying a conditional type:

Predefined conditional types

TypeScript adds several predefined conditional types, you can find the full list and examples in Utility Types .

Nightly Builds

How to use a nightly build of TypeScript

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

Daniel Rosenwasser  (65)

Last updated: Apr 29, 2024  

  • Books Get Your Hands Dirty on Clean Architecture Stratospheric
  • Contribute Become an Author Writing Guide Author Workflow Author Payment
  • Services Book me Advertise
  • Categories Spring Boot Java Node Kotlin AWS Software Craft Simplify! Meta Book Reviews

Operators in TypeScript

  • August 1, 2023

TypeScript is a superset of JavaScript that adds static typing and other features to the language. Its operators are crucial to understanding the language and writing effective code.

Operators are symbols or keywords in a programming language that perform operations on values, such as arithmetic operations, string concatenation, and comparisons.

Understanding operators in TypeScript is essential because they are fundamental building blocks of the language and are used in almost every programming aspect. By choosing the right operator for the job, you can often simplify your code and make it easier to understand and maintain. In this article, we will explore the most important operators in TypeScript and provide examples of how they can be used in real-world applications to help you write more efficient and readable code.

Example Code

What operators are in typescript.

In Typescript, operators are symbols used to perform operations on variables or values. They can be classified into several categories based on their functions.

Concatenation Operators

Concatenation operators in TypeScript are used to combine strings and values together. The most common concatenation operator is the plus sign (+). When used with strings, the plus sign combines them into a single string. When used with a string and another data type (other than a string), the plus sign concatenates it to the end of the string.

For example, let’s say we have two strings, “Hello” and “World”. We can use the concatenation operator to combine them into a single string:

We can also use the concatenation operator to combine a string and a value:

In this example, the concatenation operator combines the string “I am " with the value of the age variable (30) and the string " years old.” to create the final message.

Concatenation operators are useful in situations where we need to build dynamic strings based on values or user input. Using concatenation operators, we can create custom messages or outputs tailored to our specific needs.

Arithmetic Operators

Arithmetic operators allow us to perform mathematical operations such as addition, subtraction, multiplication, division etc. on numerical values (constants and variables). Let’s take a look at them:

Addition ( + ): adds two or more values. The addition operator (+) can also perform string concatenation when used with strings. More information is in the Concatenation Operators section.

Subtraction ( - ): subtracts two or more values

Multiplication ( * ): multiplies two or more values, and the precision of the result depends on the data types involved. When multiplying two integers, the result will also be an integer, preserving the whole number portion of the calculation. Similarly, when multiplying two floats, the result will also be a float, retaining the decimal precision. When we multiply an integer by a float or a float by an integer, the result will be a float. In TypeScript, the multiplication operation between an integer and a float promotes the integer to a float and performs the multiplication as a floating-point operation. The resulting value will retain the decimal precision of the float and include any fractional component.

Division ( / ): divides two or more values, and the precision and data type of the result depend on the types of the operands. If we divide two integers, the result will be an integer, and any decimal portion will be truncated. For example, 5 / 2 would result in 2 , as the remainder is discarded. However, if either the numerator or denominator is a float, the result will be a float. Dividing an integer by a float or a float by an integer will yield a float result, preserving decimal precision.

Modulus ( % ): returns the remainder of a division operation.

Increment ( ++ ): increases the value of the variable by one.

Decrement ( -- ): decreases the value of the variable by one.

If used with non-number variables, with the exception of the + operator, TypeScript’s compiler will not allow these operations and raise a compilation error.

Relational Operators

Relational Operators are used to compare two values and determine their relationship. Let’s take a look at some relational operators commonly used in Typescript:

Equality Operator ( == ): This operator compares two values but doesn’t consider their data types. If the values are equal, it returns true. Otherwise, it returns false. When comparing non-number variables with the Equality operator ( == ), it will check their data type. If the non-number variables have different data types, it will attempt to convert them to a common type. For example, if one variable is a string and the other is a number, it will try to convert the string to a number before performing the comparison. The result of the comparison will be true if the converted values are equal, and false otherwise. It’s worth noting that using the Equality operator ( == ) for non-numerical variables can lead to unexpected behaviour due to type coercion, and it’s generally recommended to use the Strict Equality operator ( === ) for more predictable comparisons.

Strict Equality Operator ( === ): This operator compares two values for equality, and it considers their data types. If the values are equal in value and type, it returns true. Otherwise, it returns false. When comparing non-numerical variables, it performs a strict comparison without type conversion. If the variables have different data types, the comparison returns false. It returns true only when the variables have the same data type and value.

Inequality Operator ( != ): This operator compares two values for inequality. If the values are not equal, it returns true. Otherwise, it returns false.

Strict Inequality Operator ( !== ): This operator compares two values for inequality, and considers their data types. It returns true if the values are not equal in value or type. Otherwise, it returns false.

Greater Than Operator ( > ): This operator checks if the left operand is greater than the right operand. If it is, it returns true. Otherwise, it returns false. When used with strings, it performs a lexicographical comparison. It checks if the left operand appears after the right operand in lexicographical order. For example, "apple" > "banana" would return false since “apple” comes before “banana” in lexicographical order.

Less Than Operator ( < ): This operator checks if the left operand is less than the right operand. If it is, it returns true. Otherwise, it returns false. When used with strings, it checks if the left operand appears before the right operand in lexicographical order. For example, "apple" < "banana" would return true since “apple” comes before “banana” in lexicographical order.

Greater Than or Equal To Operator ( >= ): This operator checks if the left operand is greater than or equal to the right operand. If it is true, it returns true. Otherwise, it returns false. When used with strings, it checks if the left operand is greater than or equal to the right operand. For example, "apple" >= "banana" would return false since “apple” is not greater than or equal to “banana”.

Less Than or Equal To Operator ( <= ): This operator checks if the left operand is less than or equal to the right operand. If it is true, it returns true. Otherwise, it returns false. When used with strings, it checks if the left operand is smaller than or equal to the right operand. For example, "apple" <= "banana" would return true since “apple” is less than “banana”.

Difference Between Equality and Strict Equality Operator

When it comes to comparing values, it is essential to understand the difference between the equality ( == ) and strict equality ( === ) operators. The equality operator only compares the values of the operands, while the strict equality operator compares both the values and types of the operands. Let’s take a look at this code:

  • In the given example, the expression x == y returns false because the values of x and y are not equal.
  • The expression x == 10 returns true because x is equal to 10 .
  • The expression x === y returns false because x and y are of the same type but of different values.
  • The expression x === '10' returns false because x is a number and '10' is a string (i.e. they are of different types).
  • Finally, the expression x === 10 returns true because both x and 10 are of the same data type (number) and have the same value.

Logical Operators

Logical operators in TypeScript allow you to perform logical operations on boolean values. ​​Let’s take a look at some Logical Operators:

AND ( && ) Operator: The AND && operator returns true if both operands are true.

OR ( || ) Operator: The OR || operator returns true if at least one of the operands is true.

NOT ( ! ) Operator: The NOT ! operator negates a boolean value, converting true to false and vice versa.

Bitwise Operators

Bitwise operators in TypeScript operate on binary representations of numbers. They are useful for performing operations at the binary level, manipulating individual bits, working with flags, or optimizing certain algorithms that require low-level bit manipulations. Understanding their behaviour and how to use them correctly can be valuable when working with binary data or implementing certain advanced programming techniques.

Some of the common bitwise operators include AND ( & ), OR ( | ), XOR ( ^ ), left shift ( << ), right shift ( >> ), and complement ( ~ ). These operators are particularly useful when working with flags, binary data, or performance optimizations. Let’s take a look at them:

AND ( & ): The AND operator, represented by the symbol & , performs a logical AND operation between corresponding bits of two numbers. The result is a new number where each bit is set to 1 only if both bits in the same position of the operands are 1.

OR ( | ): The OR operator, represented by the symbol | , performs a logical OR operation between corresponding bits of two numbers. The result is a new number where each bit is set to 1 if at least one of the bits in the same position of the operands is 1.

XOR ( ^ ): The XOR operator, represented by the symbol ^ , performs a logical exclusive OR operation between corresponding bits of two numbers. The result is a new number where each bit is set to 1 only if one of the bits in the same position of the operands is 1, but not both.

Left Shift ( << ): The left shift operator, represented by the symbol << , shifts the binary bits of a number to the left by a specified number of positions. The leftmost bits are discarded, and new zeros are added on the right side. Each shift to the left doubles the value of the number.

Right Shift ( >> ): The right shift operator, represented by the symbol >> , shifts the binary bits of a number to the right by a specified number of positions. The rightmost bits are discarded, and new zeroes are added on the left side. For positive numbers, each shift to the right halves the value of the number.

Complement ( ~ ): The complement operator, represented by the symbol ~ , performs a bitwise NOT operation on a number, flipping all its bits. This operator effectively changes each 0 to 1 and each 1 to 0.

By mastering the usage of these operators and applying best practices, you can enhance your TypeScript programming skills and develop more effective solutions. Whether you’re working on small-scale projects or large-scale applications, a solid understanding of operators will contribute to your success in writing maintainable and performant code.

You can find all the code used in this article on GitHub .

Muhammad Irtaza

typescript assignment operators

Irtaza is a game developer who is always on the lookout for new and innovative ways to create games. He is a creative, passionate, and talented writer who is always looking for new challenges and loves sharing his knowledge and expertise with others.

Recent Posts

Publisher-Subscriber Pattern Using AWS SNS and SQS in Spring Boot

  • Spring Boot

Publisher-Subscriber Pattern Using AWS SNS and SQS in Spring Boot

Hardik Singh Behl

  • May 3, 2024

In an event-driven architecture where multiple microservices need to communicate with each other, the publisher-subscriber pattern provides an asynchronous communication model to achieve this.

Optimizing Node.js Application Performance with Caching

Optimizing Node.js Application Performance with Caching

Olaoluwa Ajibade

  • April 20, 2024

Endpoints or APIs that perform complex computations and handle large amounts of data face several performance and responsiveness challenges. This occurs because each request initiates a computation or data retrieval process from scratch, which can take time.

Bubble Sort in Kotlin

Bubble Sort in Kotlin

  • Ezra Kanake
  • April 14, 2024

Bubble Sort, a basic yet instructive sorting algorithm, takes us back to the fundamentals of sorting. In this tutorial, we’ll look at the Kotlin implementation of Bubble Sort, understanding its simplicity and exploring its limitations.

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)

TypeScript Operator

Switch to English

Table of Contents

Types of TypeScript Operators

Arithmetic operators, logical operators, relational operators, bitwise operators, assignment operators, ternary/conditional operators, string operators, type operators, tips and common error-prone cases.

Introduction Understanding TypeScript operators is a fundamental part of learning TypeScript. TypeScript operators are symbols used to perform operations on operands. An operand can be a variable, a value, or a literal.

  • Ternary/conditional Operators
  • Always use '===' instead of '==' for comparisons to avoid type coercion.
  • Remember that the '&&' and '||' operators return a value of one of the operands, not necessarily a boolean.
  • Be careful when using bitwise operators as they can lead to unexpected results due to JavaScript's internal number representation.
  • Use parentheses to ensure correct order of operations when combining operators in complex expressions.
  • Remember that the '+' operator behaves differently with strings, leading to unexpected results.

Logical assignment operators in Typescript

Portrait of Tom

Hi there, Tom here! As of writing, Typescript 4's stable release is imminent (August 2020) and with it are some very nice changes to come.

Typescript 4 ahead

One of those is the addition of logical assignment operators, which allow to use the logical operators with an assignment. As a reminder, here are the logical operators being used for the new logical assignment operators:

These new logical assignment operators themselves are part of the collection of compound assignment operators , which apply an operator to two arguments and then assign the result to the left side. They are available in many languages and now get enhanced in Typescript.

Code, please!

What does that mean? You probably already know a few compound assignment operators:

The new logical assignment operators now give you the ability to use your logical operator of choice for the same kind of assignment:

Note that these new operators were already available in JS and are also natively suppported by V8.

And that’s about it for one of Typescript 4’s great new features. Thanks for the quick read and I hope you could learn something!

expressFlow is now Lean-Forge

Advanced TypeScript Types Cheat Sheet (with Examples)

Ibrahima Ndaw

TypeScript is a typed language that allows you to specify the type of variables, function parameters, returned values, and object properties.

Here an advanced TypeScript Types cheat sheet with examples.

Let's dive in.

Intersection Types

Union types, generic types, utility types, nonnullable.

  • Mapped Types

Type Guards

Conditional types.

An intersection type is a way of combining multiple types into one. This means that you can merge a given type A with a type B or more and get back a single type with all properties.

As you can see, IntersectionType combines two types - LeftType and RightType and uses the & sign to construct the intersection type.

Union types allow you to have different types annotation within a given variable.

The function showType is a union type that accepts both strings and numbers as a parameter.

A generic type is a way of reusing part of a given type. It helps to capture the type T passed in as a parameter.

To construct a generic type, you need to use the brackets and pass T as a parameter. Here, I use T (the name is up to you) and then, call the function showType twice with different type annotations because it's generic - it can be reused.

Here, we have another example that has an interface GenericType which receives a generic type T . And since it's reusable, we can call it first with a string and then a number.

A generic type can receive several arguments. Here, we pass in two parameters: T and U , and then use them as type annotations for the properties. That said, we can now use the interface and provide different types as arguments.

TypeScript provides handy built-in utilities that help to manipulate types easily. To use them, you need to pass into the <> the type you want to transform.

  • Partial<T>

Partial allows you to make all properties of the type T optional. It will add a ? mark next to every field.

As you can see, we have an interface PartialType which is used as type annotation for the parameters received by the function showType() . And to make the properties optional, we have to use the Partial keyword and pass in the type PartialType as an argument. That said, now all fields become optional.

  • Required<T>

Unlike Partial , the Required utility makes all properties of the type T required.

The Required utility will make all properties required even if we make them optional first before using the utility. And if a property is omitted, TypeScript will throw an error.

  • Readonly<T>

This utility type will transform all properties of the type T in order to make them not reassignable with a new value.

Here, we use the utility Readonly to make the properties of ReadonlyType not reassignable. That said, if you try to give a new value to one of these fields, an error will be thrown.

Besides that, you can also use the keyword readonly in front of a property to make it not reassignable.

  • Pick<T, K>

It allows you to create a new type from an existing model T by selecting some properties K of that type.

Pick is a bit different from the previous utilities we have already seen. It expects two parameters - T is the type you want to pick elements from and K is the property you want to select. You can also pick multiple fields by separating them with a pipe( | ) symbol.

  • Omit<T, K>

The Omit utility is the opposite of the Pick type. And instead of selecting elements, it will remove K properties from the type T .

This utility is similar to the way Pick works. It expects the type and the properties to omit from that type.

  • Extract<T, U>

Extract allows you to construct a type by picking properties that are present in two different types. The utility will extract from T all properties that are assignable to U .

Here, we have two types that have in common the property id . And hence by using the Extract keyword, we get back the field id since it's present in both interfaces. And if you have more than one shared field, the utility will extract all similar properties.

Unlike Extract , the Exclude utility will construct a type by excluding properties that are already present in two different types. It excludes from T all fields that are assignable to U .

As you can see here, the properties firstName and lastName are assignable to the SecondType type since they are not present there. And by using the Extract keyword, we get back these fields as expected.

  • Record<K,T>

This utility helps you to construct a type with a set of properties K of a given type T . Record is really handy when it comes to mapping the properties of a type to another one.

The way Record works is relatively simple. Here, it expects a number as a type which is why we have 0, 1, and 2 as keys for the employees variable. And if you try to use a string as a property, an error will be thrown. Next, the set of properties is given by EmployeeType hence the object with the fields id, fullName, and role.

  • NonNullable<T>

It allows you to remove null and undefined from the type T .

Here, we pass the type NonNullableType as an argument to the NonNullable utility which constructs a new type by excluding null and undefined from that type. That said, if you pass a nullable value, TypeScript will throw an error.

By the way, if you add the --strictNullChecks flag to the tsconfig file, TypeScript will apply non-nullability rules.

Mapped types

Mapped types allow you to take an existing model and transform each of its properties into a new type. Note that some utility types covered earlier are also mapped types.

StringMap<> will transform whatever types that passed in into a string. That said, if we use it in the function showType() , the parameters received must be a string - otherwise, an error will be thrown by TypeScript.

Type Guards allow you to check the type of a variable or an object with an operator. It's a conditional block that returns a type using typeof , instanceof , or in .

As you can see, we have a normal JavaScript conditional block that checks the type of the argument received with typeof . With that in place, you can now guard your type with this condition.

Like the previous example, this one is also a type guard that checks if the parameter received is part of the Foo class or not and handles it consequently.

The in operator allows you to check whether a property x exists or not on the object received as a parameter.

Conditional types test two types and select one of them depending on the outcome of that test.

This example of the NonNullable utility type checks if the type is null or not and handle it depending on that. And as you can note, it uses the JavaScript ternary operator.

Thanks for reading.

You can find other great content like this on my blog or follow me on Twitter to get notified.

JavaScript enthusiast, Full-stack developer & blogger

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

IMAGES

  1. TypeScript Tutorial

    typescript assignment operators

  2. What are operators

    typescript assignment operators

  3. TypeScript Operators

    typescript assignment operators

  4. #3 TypeScript Tutorial for Beginners

    typescript assignment operators

  5. Assignment Operators in C

    typescript assignment operators

  6. TypeScript

    typescript assignment operators

VIDEO

  1. Typescript Type System explained by Anders Hejlsberg

  2. Assignment Operators in Typescript

  3. Zoom Class 02 07 Aug 2023 Basics of Typescript Operators

  4. Typescript

  5. 13 assignment operator in javascript

  6. Typescript Type Guards