The satisfies keyword is a type-checking operator introduced in TypeScript 4.9. It allows you to validate that a value matches a specific type while still preserving the literal and detailed structure of the value itself.
This operator is useful when you want to make sure an object fits a particular shape but don’t want TypeScript to widen the type or throw away extra information. In other words, it helps you keep strong type safety without losing useful data.
The main benefit of using the satisfies keyword is that it gives you both safety and precision.
When you use as, TypeScript may let things slide or widen types in ways you don’t intend. With satisfies, TypeScript checks that your value conforms to the target type at compile time, and it will give an error if it doesn’t.
At the same time, satisfies doesn’t throw away the extra fields or narrow literal types — it keeps them available for IntelliSense and other autocomplete tooling.
type User = {
  id: number;
  role: 'admin' | 'user';
};
const admin = {
  id: 1,
  role: 'admin',
  extra: 'metadata' // extra field not part of User
} satisfies User; // Valid: has all required fields of User
// The object passes type checking, but `admin.extra` is still accessible.In this example, TypeScript confirms that the object has all the required fields from the User type. At the same time, it preserves the extra property and the exact string value 'admin' for later use.
Developers often use the as keyword to tell TypeScript to treat a value as a certain type. However, as simply forces the type and does not validate the structure.
const user1 = {
  id: 1
} as User; // No error! But 'role' is missing — this could lead to bugsTypeScript trusts you with as and skips strict validation. This can lead to runtime issues if something is missing.
With satisfies, TypeScript ensures the object matches the type exactly.
const user2 = {
  id: 1
} satisfies User; // Compile-time error: Property 'role' is missingThis is a safer approach because it ensures your object truly matches the type. That’s why many developers are now preferring satisfies over as.
The extends keyword is used when you’re working with types, not values. It’s mainly used to build on top of other types, for example, to create a more specific version of a base type.
Here’s how extends works in type declarations:
type User = {
  id: number;
  role: 'admin' | 'user';
};
type Admin = User & {
  accessLevel: number;
};
// or using extends syntax for generics
type ApiResponse<T> = {
  status: number;
  data: T;
};
type UserResponse = ApiResponse<User>;
In the first example, Admin extends User by adding a new field accessLevel. This lets you reuse and build on existing types.
But you can’t use extends directly on values — that’s where satisfies comes in.
const superAdmin = {
  id: 2,
  role: 'admin',
  accessLevel: 10
} satisfies Admin; // Valid: includes all required fields from AdminIf you omit a required field, TypeScript will show a compile-time error:
const invalidAdmin = {
  id: 2,
  role: 'admin'
} satisfies Admin; // Error: Property 'accessLevel' is missingSo in short:
- Use extendswhen you’re defining or combining types.
- Use satisfieswhen you’re validating a value against a type at compile time.
They serve different purposes:extends creates relationships between types,satisfies checks relationships between values and types.
You can use satisfies with Record to validate that an object fits a key-value structure.
const config = {
  theme: 'dark',
  layout: 'grid'
} satisfies Record<string, string>; // All values are stringsIf one of the values is the wrong type, TypeScript will catch it:
const invalidConfig = {
  theme: 'dark',
  debug: true
} satisfies Record<string, string>; // Error: boolean is not assignable to stringHere’s an example where satisfies is used with a custom type, but the object includes extra properties.
type Point = {
  x: number;
  y: number;
};
const origin = {
  x: 0,
  y: 0,
  label: 'origin point' // not part of Point
} satisfies Point; // Valid: has all required fields from PointYou get type safety on required fields, and the extra fields are preserved in the variable’s full type.
satisfies can be combined with generics such as Record<string, unknown> to enforce shape on dynamic objects.
const data = {
  id: 123,
  isActive: true
} satisfies Record<string, unknown>; // Valid: both values fit 'unknown'If any value doesn’t match the constraints of the type, TypeScript will warn you.
Use satisfies when:
- You want to validate that a value matches a type at compile time
- You want to keep extra fields for extended use or flexibility
- You’re working with configuration, settings, themes, or constant maps
- You want to preserve literal types for better IntelliSense
- You care about stronger type checking than what asgives you
The satisfies keyword in TypeScript is a valuable tool for enforcing type correctness without sacrificing extra information or developer experience. Compared to as, it provides safer compile-time validation. And unlike extends, it works directly with values.
Whether you’re validating configuration objects, working with Record types, or building flexible systems with strong type checks, satisfies gives you a modern, precise way to write reliable TypeScript code.
If you enjoyed this article, I’d truly appreciate it if you could share it—it really motivates me to keep creating more helpful content!
If you’re interested in exploring more, check out these articles.
- 4 Ways To Handle Asynchronous JavaScript
- Overloading vs Overriding in TypeScript
- How to Use Discriminated Unions in TypeScript?
Thanks for sticking with me until the end—I hope you found this article valuable and enjoyable!
Want more dev insights like this? Subscribe to get practical tips, tutorials, and tech deep dives delivered to your inbox. No spam, unsubscribe anytime.


