Top Types & Bottom Types
In the previous chapter, we expanded our understanding of types with narrowing, widening, and immutability using const assertions. In this chapter, we will explore TypeScript’s top types (any
and unknown
), the bottom type (never
), and the special type (void
).
Top Types: any
and unknown
The Flexibility of any
The any
type is a universal type that can hold any value. While this provides flexibility, it disables type checking, which can lead to runtime errors. Here’s an example:
The TypeScript team strongly advises against using any
unless transitioning a JavaScript codebase to TypeScript. For safer alternatives, let’s explore unknown
.
The Power of unknown
Introduced in TypeScript 3.0, unknown
is a type-safe alternative to any
. It requires developers to narrow down the type using control flow before accessing its properties:
By enforcing these checks, unknown
ensures type safety and prevents runtime crashes.
Practical Use of unknown
In testing scenarios, mock objects often replace real implementations. Type assertions with unknown
can help circumvent strict type checks temporarily:
This approach strips type information with unknown
before reasserting the desired type.
Bottom Type: never
The never
type represents values that never occur. It’s typically used for unreachable code or exhaustive checks in TypeScript:
Example:
By leveraging never
in the default case, TypeScript ensures that all possible cases are handled. Adding a new status, like "IDLE"
, would trigger a compile-time error until it is explicitly handled.
No Type: void
The void
type represents the absence of a return value. It is commonly used for functions that perform actions without returning anything:
Comparison: void
and undefined
While void
and undefined
may seem similar, they have distinct purposes. A function with an undefined
return type must explicitly return undefined
, while a void
function does not:
In scenarios where the return value is irrelevant, void
is preferred to communicate the lack of interest in the return type.
What You Have Learned
Top Types: any
and unknown
: You have learned about TypeScript’s top types, any
and unknown
. The any
type allows a variable to hold any value to mimic JavaScript’s standard behaviour, potentially causing runtime errors. The unknown
type, introduced in TypeScript 3.0, provides a safer alternative by requiring explicit type narrowing before accessing properties, ensuring type safety.
Bottom Type: never
: You now understand that the never
type represents values that never occur. It’s useful for situations like unreachable code or exhaustive checks, ensuring that all possible cases are handled in TypeScript.
No Type: void
: You’ve learned that the void
type is used for functions that do not return a value. It signals the absence of a return value, distinguishing it from undefined
, which requires explicit returning of undefined
. The void type is useful in your code to indicate that the return value is not important or relevant.
Quiz
- Which statement best describes the
any
type in TypeScript?
- a) It allows you to assign only
string
andnumber
values. - b) It is the safest type for any unknown data structure.
- c) It can hold any value and was designed to mimic JavaScript's original type behaviour.
- d) It restricts object properties to a known subset.
- What must you do before accessing properties on a variable typed as
unknown
?
- a) Assign it to an intermediate variable of type
any
. - b) Perform type checks or narrowing to confirm its structure.
- c) Cast it to
string
and then access properties. - d) Nothing,
unknown
behaves exactly likeany
.
- How is the
never
type typically used in TypeScript?
- a) For return values of functions that never return.
- b) For variables that can accept any type of value.
- c) For optional properties in interfaces.
- d) As a shorthand for
undefined
in TypeScript.
- What does TypeScript enforce if you include a
never
type in a switch statement’s default case?
- a) It allows partial coverage of cases without error.
- b) It automatically converts all other cases to
any
. - c) It ensures all possible cases are exhaustively handled.
- d) It disables type checking within the
switch
block.
- Which statement correctly explains the difference between
void
andundefined
in a function return type?
- a) A function returning
void
must explicitly returnundefined
. - b) Both
void
andundefined
require a return statement. - c) Using
void
indicates no meaningful return value;undefined
means the function must explicitly returnundefined
. - d)
void
is only valid in strict mode, whereasundefined
is not.
- Which approach ensures runtime immutability for an object in JavaScript in addition to TypeScript compile-time checks?
- a) Declaring the object with
unknown
. - b) Using
as const
in TypeScript, which automatically freezes the object at runtime. - c) Calling
Object.freeze()
on the object in strict mode. - d) Specifying the object’s type as
never
to prevent reassignment.