Alexandroppolus
@Alexandroppolus
кодир

Баг тайпчекинга параметров функции?

Код:
type AB = {
    a: number
    b: string
}

type A = {
    a: number
}

interface Int1 {
    f(p: A): void
    // f: (p: A) => void
}

class Class1 implements Int1 {
    f(p: AB): void { console.log(p) }
    // f = (p: AB) => { console.log(p) }
}

var o: Int1 = new Class1();

o.f({a: 1})


По закону контравариантности, Class1 не реализует интерфейс Int1, потому что классовый метод f не сможет принимать параметр типа А.
Тем не менее, тайпчекинг помалкивает.

Если в интерфейсе поменять определение f (закомментить-раскомментить), то ошибка подсвечивается, независимо от того, как запишем функцию в классе.

Может я чего не понимаю в этой форме? f(p: A): void Но если тут вместо А подставить, например, число, то всё норм, есть ошибка.
  • Вопрос задан
  • 140 просмотров
Решения вопроса 1
Отличный вопрос.

Strict function types:
The stricter checking applies to all function types, except those originating in method or constructor declarations. Methods are excluded specifically to ensure generic classes and interfaces (such as Array) continue to mostly relate covariantly.

При замене методов на обычные функции сразу появляется ошибка:
type AFnc = (p: A) => void

function foo(p: A): void { }
function bar(p: AB): void { }

const f: AFnc = foo;
const b: AFnc = bar; // не компилируется с сообщением о том, что AB требует ещё и свойство b
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
WblCHA
@WblCHA
Потому что АВ ─ это частный случай А.
Грубо говоря, тайпскрипт сравнивает не названия интерфейсов, а их свойства и их типы. То есть ты можешь передавать любой тип, который является частным случаем типа, который необходим.
Если поменяешь в АВ тип свойства а на string, то ошибка сразу же появится.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы