When it comes to type compatibility in TypeScript, it follows a structural subtyping approach rather than nominal typing. To illustrate this point, consider the following interface definitions:
interface IFoo { X: number }
interface IBar { X: number; Y: number }
Does IBar
extend IFoo
? Not quite.
However, is IFoo
compatible with IBar
? Indeed it is.
The members of IFoo
form a subset of IBar
members, allowing for the assignment of any IBar
to IFoo
. The reverse operation is not possible:
var x: IFoo;
var y: IBar;
x = y // perfectly valid
y = x // results in a type error due to missing Y member in x
In TypeScript, all types can be considered compatible with Object
, akin to treating it as an empty interface. This feature enables smooth interaction with JavaScript libraries by passing any valid TypeScript value to functions accepting Object
.
I recommend delving into the details of Type Compatibility explained in the documentation, particularly focusing on the distinction between Subtype vs Assignment.