en.wikipedia.org/wiki/Nominal_type_system

е, в TypeScript абсолютно нормально (с точки зрения компилятора) иметь такой код:

class Vehicle {
    public run(): void { console.log('Vehicle.run'); }
}

class Task {
    public run(): void { console.log('Task.run'); }
}

function runTask(t: Task) {
    t.run();
}

runTask(new Task());
runTask(new Vehicle());

Но в то же время я ожидалошибка компиляции, потому чтоVehicle а такжеTask не имеет ничего общего.

А такжездравомыслящий использование может быть реализовано через явное определение интерфейса:

interface Runnable {
    run(): void;
}

class Vehicle implements Runnable {
    public run(): void { console.log('Vehicle.run'); }
}

class Task implements Runnable {
    public run(): void { console.log('Task.run'); }
}

function runRunnable(r: Runnable) {
    r.run();
}

runRunnable(new Task());
runRunnable(new Vehicle());

... или общий родительский объект:

class Entity {
    abstract run(): void;
}

class Vehicle extends Entity {
    public run(): void { console.log('Vehicle.run'); }
}

class Task extends Entity {
    public run(): void { console.log('Task.run'); }
}

function runEntity(e: Entity) {
    e.run();
}

runEntity(new Task());
runEntity(new Vehicle());

И да, для JavaScript абсолютно нормально иметь такое поведение, потому что нет классов и нет компилятора вообще (только синтаксический сахар), и типизация утки является естественной для языка. Но TypeScript пытается ввести статические проверки, классы, интерфейсы и т. Д. Однако, по моему мнению, типизация утки для экземпляров классов выглядит довольно запутанно и подвержена ошибкам.

Ответы на вопрос(1)

Ваш ответ на вопрос