If the method is declared as a interface function, then it's possible for you to add more overload versions.
interface Logger {
log(message: string): void;
}
interface Logger {
log(message: string, level: string): void;
}
Declaring method as a property, on the other hand, prevents you from duplicating the property declarations which have different types:
interface Logger {
log: (message: string) => void;
}
interface Logger {
log: (message: string, level: string) => void;
}
TypeScript generates different output for a class that implements the interface methods.
Assume that we have a class ConsoleLogger
that simply logs the message in the Console window.
For the first approach:
interface Logger {
log: (message: string) => void;
}
class ConsoleLogger implements Logger {
log = (message: string) => {
console.log(message);
};
}
For the second approach:
interface Logger {
log(message: string): void;
}
class ConsoleLogger implements Logger {
log(message: string) {
console.log(message);
}
}
Looking at the generated JavaScript codes, you'll see the different outputs.
The first approach produces a property log
in the constructor. It means that log
will be created every time you create a new instance of class.
While the second approach produces the log
method, and it exists in all instances of class. The log
method also is a member of class prototype, so we can extend the class to override the method if needed:
class ConsoleLogger implements Logger {
log(message: string) {
console.log(message);
}
}
class ConsoleLoggerWithColor extends ConsoleLogger {
log(message: string) {
console.log('%c%s', 'color: white; background: blue', message);
}
}
See the
differences between declaring methods in class constructor and prototype for more details.