Learn how to safely handle variables of an unknown type in TypeScript and understand the differences between `unknown` and `any`.
unknown
TypeIn this section, we’ll explore the unknown
type in TypeScript, a powerful tool for safely handling variables when their types are not known at compile time. We’ll compare it with the any
type, demonstrate how to work with unknown
using type narrowing techniques, and discuss best practices for its use in function parameters and return types.
unknown
TypeThe unknown
type was introduced in TypeScript 3.0 as a safer alternative to the any
type. When you declare a variable with the unknown
type, you are essentially telling TypeScript that you don’t know what type it is. Unlike any
, which allows you to perform any operation on the variable without any checks, unknown
requires you to perform some form of type checking or type assertion before you can use it in a meaningful way.
unknown
?unknown
type forces you to perform type checks before using the variable, reducing the risk of runtime errors.unknown
helps maintain type safety across your codebase.unknown
with any
To understand the benefits of unknown
, let’s compare it with the any
type.
any
TypeThe any
type is a wildcard type that allows you to bypass TypeScript’s type checking. While it can be useful in certain scenarios, it can also lead to potential issues:
any
, you can perform any operation on the variable without any compile-time checks, which can lead to runtime errors.any
can make your code harder to understand and maintain, as it obscures the intended types of variables.unknown
TypeThe unknown
type addresses these issues by requiring explicit type checks:
unknown
variable without first narrowing its type.unknown
encourages better coding practices and clearer code.unknown
VariablesTo use an unknown
variable, you need to narrow its type to a more specific type before performing any operations. Let’s explore some common techniques for type narrowing.
Type Guards: Use typeof
or instanceof
to check the type of a variable.
function processValue(value: unknown) {
if (typeof value === "string") {
console.log("String value:", value.toUpperCase());
} else if (typeof value === "number") {
console.log("Number value:", value.toFixed(2));
} else {
console.log("Unknown type");
}
}
Type Assertions: Use the as
keyword to assert a specific type.
function getLength(value: unknown): number {
if (typeof value === "string") {
return (value as string).length;
} else if (Array.isArray(value)) {
return (value as Array<any>).length;
}
return 0;
}
User-Defined Type Guards: Create custom functions to check types.
function isString(value: unknown): value is string {
return typeof value === "string";
}
function printValue(value: unknown) {
if (isString(value)) {
console.log("String:", value);
} else {
console.log("Not a string");
}
}
unknown
Over any
The unknown
type is preferable over any
in scenarios where you want to ensure type safety and maintainability. Here are some examples:
Function Parameters: When the input type is not known, use unknown
to enforce type checks within the function.
function handleInput(input: unknown) {
if (typeof input === "string") {
console.log("Handling string input:", input);
} else {
console.log("Handling non-string input");
}
}
API Responses: When dealing with data from external sources, such as API responses, use unknown
to ensure the data is validated before use.
async function fetchData(url: string): Promise<unknown> {
const response = await fetch(url);
return response.json();
}
async function processData() {
const data = await fetchData("https://api.example.com/data");
if (typeof data === "object" && data !== null) {
console.log("Data is an object:", data);
} else {
console.log("Data is not an object");
}
}
unknown
unknown
types before performing operations.unknown
is safer than any
, avoid overusing it. Use specific types whenever possible.unknown
to improve code readability.Let’s put your knowledge to the test! Try modifying the following code examples to handle different types of input:
processValue
function to handle boolean values.getLength
function to return the length of a Set if the input is a Set.isNumber
that checks if a value is a number and use it in the printValue
function.To help you understand how unknown
works, let’s visualize the process of type narrowing using a flowchart.
flowchart TD A[Start] --> B{Is value a string?} B -->|Yes| C[Use string methods] B -->|No| D{Is value a number?} D -->|Yes| E[Use number methods] D -->|No| F[Handle unknown type] C --> G[End] E --> G F --> G
This flowchart illustrates the decision-making process when working with an unknown
variable. By checking the type and narrowing it down, we can safely perform operations on the variable.
For more information on the unknown
type and type narrowing, check out these resources:
unknown
TypeTo reinforce your understanding, consider these questions:
unknown
over any
?unknown
type?unknown
over specific types?unknown
type is a safer alternative to any
, requiring type checks before use.unknown
variables.unknown
over any
in scenarios where type safety is important, such as function parameters and API responses.