TypeScript: Assertions
Assertions
In TypeScript, assertions are expressions used to inform the TypeScript compiler about the type of a variable or expression when the type is known to you but cannot be automatically inferred by the compiler. Assertions are a way to provide explicit type information, essentially overriding TypeScript's inherent type inference mechanisms.
Here are the built-in assertions in TypeScript.
as const
The as const
assertion converts a variable to a constant, making all its properties readonly.
let example = { x: 10, y: 20 } as const;
// example
x = 15; // Error: Cannot assign to 'x' because it is a read-only property.
as [type]
The as [type] assertion specifies the type of an expression where the type is known but TypeScript cannot infer it.
let someValue: any = "This is a string";
let strLength: number = (someValue as string).length;
another example
interface Person {
name: string;
age: number;
}
// Let's say we have a variable `unknownPerson` of type `any`:
let unknownPerson: any = { name: "Alice", age: 30 };
// We know more about the type, so we assert it to the `Person` type:
let person: Person = unknownPerson as Person;
console.log(person.name); // Output: Alice
console.log(person.age); // Output: 30
as any
The as any assertion opts-out of type checking for a variable.
let vaguelyTyped: any = "could be anything";
let strLength: number = (vaguelyTyped as any).length;
Non-null Assertions
Non-null assertions are a way to tell the TypeScript compiler that you are certain a value will not be null
or undefined
at the time it is used, even when TypeScript's type checking might consider such a case possible. This assertion can be particularly useful when you are confident about the presence of a value due to the logic of your application, but TypeScript's static analysis cannot infer this certainty.
Syntax of Non-null Assertions
- Postfix
!
Operator: Placed after the variable or expression, it removes null and undefined from the type. - Using
as
Type Assertion: Explicitly asserting that the variable is not null or undefined.
Example Usage
// Assume we have an optional interface property which may be undefined
interface User {
id: number;
name?: string;
}
let user: User = { id: 123 };
// Using the non-null assertion to access 'name' which is optionally undefined
let userName: string = user.name!; // We assert that name is definitely not null or undefined here
// Using 'as' type assertion
let userName2: string = user.name as string; // Similarly asserting non-nullability
console.log(userName); // Note: This will throw a runtime error if name is actually undefined
Satisfies Keyword
The satisfies
keyword in TypeScript is a relatively new feature introduced in TypeScript 4.9.
It is used for type assertion, allowing you to check if a value satisfies a particular type without changing the resulting type of the expression.
This keyword is particularly useful in situations where you want to ensure that a value conforms to a specific interface or type, but you don't want to change its original type.
Purpose of the satisfies Keyword
The satisfies
keyword helps with:
- Type-checking against an interface or type: Ensuring that a value matches a specific structure without altering its type.
- Ensuring API contract compliance: Useful when implementing a function or component expected to meet certain type requirements.
- Documentation and readability: Clearly communicates the intended type conformity without affecting the underlying type of the data.
How It Works
The satisfies keyword acts like a type assertion but does not perform type casting. Instead, it checks that the value can be assigned to the type specified after satisfies and if not, TypeScript will raise a type error at compile time. However, the expression itself still retains its original type.
Example Usage
interface User {
id: number;
name: string;
email: string;
}
const user = {
id: 1,
name: "Alice",
email: "alice@example.com",
isAdmin: true,
};
// Using 'satisfies' to ensure 'user' matches the 'User' interface
user satisfies User;
// 'user' still retains its original type with 'isAdmin' property
console.log(user.isAdmin); // Outputs: true
// If we mistakenly add or omit a property, TypeScript will throw an error
const newUser = {
id: 2,
name: "Bob",
// email is missing here
isAdmin: false,
} satisfies User; // TypeScript Error: Property 'email' is missing in type ...
When to Use satisfies
- Validating Shape without Narrowing: Use it when you need to validate that an object meets a specific type interface without wanting to narrow the type of the object to that interface.
- Advanced Configuration Objects: Particularly useful for configuration objects where you expect certain properties to meet specific criteria.
- Complex Conditions: Where multiple types or interfaces may apply to a single object, and you need to ensure it meets one of them without affecting its usability elsewhere in your code.
Comments
Recent Work
Basalt
basalt.softwareFree desktop AI Chat client, designed for developers and businesses. Unlocks advanced model settings only available in the API. Includes quality of life features like custom syntax highlighting.
BidBear
bidbear.ioBidbear is a report automation tool. It downloads Amazon Seller and Advertising reports, daily, to a private database. It then merges and formats the data into beautiful, on demand, exportable performance reports.