What’s the difference   between  Unknown,  never and any

What’s the difference between Unknown, never and any

Tags
Typescript
Clean code
Published
Author
In TypeScript, we love the safety of static types to catch bugs before they hit production. But sometimes, figuring out it's kind of hard to determine the type at compile time . That's where TypeScript throws us three superhero types: anyunknown, and never. to resolve all of these kinds of problems.
So, when do we call upon each of these types? What makes anyunknown, and never special? In this journey, we're going to demystify these types, showing you when and why you should pick one of them. as we unravel the differences between anyunknown, and never, making your code safer and simpler. Let's dive in!

ANY

Any type represents any value and can be used to bypass the type checking that cost of losing type safety. But in some use cases, it is useful.

Exemple:

let mystery: any = 'a surprise!'; // Reassigning to different types mystery = 42; // No error, now a number mystery = false; // Still no error, now a boolean // Performing operations typical of different types console.log(mystery.toString()); // Works as a boolean // Reassigning to an object mystery = { key: 'value' }; console.log(mystery.key); // No error, accessing property of an object
In this example, mystery is first a string, then changes to a number, a boolean, and finally an object. The lack of type errors demonstrates the flexibility of any. It can take on various forms and still allow operations typical of its current type.

When to Use:

  • Legacy Code: In scenarios where migrating to TypeScript and specifying types is challenging, using any can ease the transition.
  • Interoperability: When working with libraries or APIs that don't provide type information.
⚠️
If you are using any as type annotation then there is no sense to use typescript. so try to Avoid any as long as possible.

UNKNOWN

On the other hand, unknown is more safer than any , because it requires type checking before using the value, making it a safer alternative when the type is not initially known.

Exemple:

let num :unknown; if(typeof num === "string") { // do something for string } else if(typeof num === "number") { // do something for number }
So that's how unknown works. When you are not sure about the type, you can assign unknown and you can check the type at runtime as I did in the above codeblock. so unknown is a type that is unknown in the compile time

When to Use:

  • Dynamic Input: When the type of a variable depends on runtime conditions.

NEVER

never type in TypeScript represents values that never occur or a function that never returns. It is a unique type that is often used in situations where the flow of the program should never reach that point.

Exemple:

 
Function that Never Returns:
function throwError(message: string): never { throw new Error(message); }
In this example, the throwError function is declared with a return type of never because it throws an error, ensuring that the function never completes its normal execution.
 
exhaustive type checking
type Fruit = 'apple' | 'banana' | 'orange'; function getFruitColor(fruit: Fruit): string { switch (fruit) { case 'apple': return 'red'; case 'banana': return 'yellow'; case 'orange': return 'orange'; default: // Using 'never' to handle exhaustive checks const exhaustiveCheck: never = fruit; throw new Error(`Unhandled fruit: ${exhaustiveCheck}`); } } // Test cases console.log(getFruitColor('apple')); // Output: 'red' console.log(getFruitColor('banana')); // Output: 'yellow' console.log(getFruitColor('orange')); // Output: 'orange' // Uncommenting the line below will result in a TypeScript error console.log(getFruitColor('grape')); // Error: Unhandled fruit: grape
In this example, getFruitColor is a function that accepts a Fruit type, which can be either 'apple''banana', or 'orange'. The never type in the default case ensures that all cases of Fruit are handled. If you try to pass a value like 'grape' that is not part of the Fruit type, TypeScript will produce a compile-time error, preventing the code from compiling. This is because 'grape' is not assignable to the Fruit type, demonstrating TypeScript's ability to catch such errors early in the development process.

When to Use:

Error Handling: Employ never when a function is designed to throw errors and never complete normally.
Exhaustive Type Checking: Utilize never when you want to enforce exhaustive type checking, ensuring that all possible cases within a certain code block are explicitly handled. This adds a layer of robustness, preventing unintended scenarios from slipping through the cracks

Conclusion : When to Use Each Type

  • Use any when you’re gradually moving from JavaScript to TypeScript or in complex dynamic logic where type safety is not a priority.
  • Use unknown for better type safety when dealing with dynamic content or third-party libraries, where the type of data is uncertain.
  • Use never in situations where you want to ensure a function doesn’t return anything or for exhaustive type checking