implements
Checks that a class satisfies an interface without changing the class type or inferring parameters.
class Name implements Interface1, Interface2 {
// members satisfying every listed interface
}- Added in TypeScript 1.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$Interface1, Interface2 | interface | object type | type alias of an object type | One or more types the class instance must be assignable to. Listing several requires the class to satisfy all of them. Unlike extends, implements accepts any number of entries. |
Errors
Errors at compile time with 'Class incorrectly implements interface' when a required member is missing or has an incompatible type. It never produces a runtime error, because the clause is erased.
Changelog
- PHP 3.0A class can implement a type alias of an object type or an intersection, not only a declared interface.
implements is an assertion, not a definition. It tells the compiler to verify that instances of this class are assignable to the listed types, then emits nothing. The class's own type is completely unaffected.
What it does not do
This is where the bug reports come from, and the handbook flags it explicitly:
- It does not infer parameter types. Writing
class C implements Checkable { check(s) { ... } }leavessas an implicitany. Contextual typing flows from an annotation or an assignment, never from animplementsclause, so you must annotate the parameters yourself. - It does not add optional members. If the interface declares
y?: numberand your class does not,c.yis an error — the class type never gained the property. - It does not create a subtype relationship at runtime. There is no
instanceofto check against, since interfaces do not exist after compilation.
When to reach for it
Use it as documentation plus a guard rail: it pins a class to a contract at its declaration site, so a missing method is reported in the class file rather than at some distant call site. Because TypeScript is structural, a class that happens to match an interface is already assignable to it whether or not you write implements — the clause only moves the error earlier.
Example
When to use it
- Pin a service class to a repository interface so a missing method fails in that file.
- Make a class satisfy several small role interfaces at once.
- Guarantee a plugin class matches the host application's expected shape at compile time.
- Catch a signature drift when an interface's method changes and the class does not.
Frequently asked questions
What is the difference between extends and implements in TypeScript?
`extends` inherits implementations and creates a real prototype link at runtime, while `implements` only checks conformance and is erased entirely. A class can extend one base class but implement any number of interfaces.
Why are my method parameters implicitly any even though the interface types them?
Because an implements clause does not contextually type the class body — the handbook states it does not change the type of the class or its methods at all. Annotate the parameters explicitly, since contextual typing only flows from a type annotation on the variable or from an assignment, not from a conformance check.
Do I need implements if the class already matches the interface?
No — TypeScript is structurally typed, so a class whose shape matches is already assignable to the interface. The clause is worth adding anyway because it reports a mismatch at the class declaration instead of at whichever call site first tries to use it.
More examples
The two things implements will not do for you
Both classes pass their implements check, yet neither behaves the way people expect. The check parameter stays implicitly any because implements does not contextually type a class body, so under noImplicitAny this is an error you must fix by annotating. And class C never gains y, because implementing an interface with an optional property does not declare that property on the class.
interface Checkable {
check(name: string): boolean;
}
class NameChecker implements Checkable {
check(s) {
// Parameter 's' implicitly has an 'any' type — no error from implements!
return s.toLowerCase() === "ok";
}
}
interface A {
x: number;
y?: number; // optional in the interface
}
class C implements A {
x = 0; // y is simply never declared
}
const c = new C();
// c.y = 10; // Property 'y' does not exist on type 'C'.
console.log(new NameChecker().check("OK"), c.x);
// true 0Implementing several contracts at once
A class can implement any number of interfaces, unlike extends which allows one base class. The sorted output confirms compareTo works as an ordinary method. The final two lines make the structural point: a plain object literal satisfies Identifiable without declaring anything, so implements adds early error reporting rather than any new capability.
interface Identifiable {
readonly id: string;
}
interface Comparable<T> {
compareTo(other: T): number;
}
class Task implements Identifiable, Comparable<Task> {
constructor(readonly id: string, readonly priority: number) {}
compareTo(other: Task): number {
return this.priority - other.priority;
}
}
const tasks = [new Task("t3", 3), new Task("t1", 1), new Task("t2", 2)];
tasks.sort((a, b) => a.compareTo(b));
console.log(tasks.map((t) => t.id).join(","));
// t1,t2,t3
// Structural typing: this object satisfies Identifiable with no implements clause.
const plain: Identifiable = { id: "plain" };
console.log(plain.id);
// plain
Discussion