Варианты реализации совместимости типов
Статические системы типов можно условно поделить на два вида: номинативные и структурные. В номинативных системах совместимость и равенство типов определяется по имени. Классический пример — java. Вот есть два класса:
class Duck {
String quackSound;
void quack();
}
class Quaker {
String quackSound;
void quack();
}
С точки зрения java — это два разных типа: имя разное, и пофиг, что начинка одинаковая. А вот в структурной системе типов это будет считаться одинаковым типом как раз потому что структура одинаковая. Структурную систему типов имеет TypeScript и этим он достаточно сильно отличается от других “мейнстримовых” языков. Джависты в шоке от того, что можно делать с помощью TypeScript, а кто-то даже предложил на нем тесты писать для java-проекта (sic!).
Еще есть утиная типизация — ее типы вообще не заботят, а только поведение. Вот такой класс
class McDuck {
Int wealth;
void quack();
}
ни по имени, ни по структуре не совпадает ни с одним из предыдущих. Но в Python все три класса будут совместимы, если от них нужен только quack
.
Разумеется, почти все практические языки не на 100% строги. В какой-нибудь Scala вполне спокойно можно организовать структурную типизацию.