Если я определяю интерфейс функции с возвращаемым типом как число, компилятор предупредит меня
interface RequestHandler {
(): number
}
// the compiler will prompt an error
// because " Type '() => boolean' is not assignable to type 'RequestHandler'"
const handler: RequestHandler = function (): boolean {
return false
}
Однако, если я это сделаю, компилятор, кажется, в порядке.
interface RequestHandler {
(): void
}
const handler: RequestHandler = function (): boolean {
return false
}
Сначала я предполагал, что функция с возвращаемым типом void будет принимать любой тип возвращаемого значения, что неверно в соответствии с этим:
// error TS2322: Type 'boolean' is not assignable to type 'void'
function foo(): void {
return true
}
Думаю, мое предположение неверно, кто-нибудь может объяснить такое поведение?
Редактировать Ответ ABOS вдохновил меня узнать больше об этом поведении Я выложу новый кусок кода в качестве демонстрации
class Animal {
eat() {}
}
// Dog is a subtype of Animal
class Dog extends Animal {
bark() {}
}
interface AnimalBuilder {
(): Animal
}
interface DogBuilder {
(): Dog
}
// DogBuilder is a subtype of Animal Builder
declare let animalBuilder: AnimalBuilder
declare let dogBuilder: DogBuilder
// this demonstrate "co-variance"
animalBuilder = dogBuilder // Ok
dogBuilder = animalBuilder // Error
interface AnimalFeeder {
(animal: Animal): void
}
interface DogFeeder {
(dog: Dog): void
}
// ...while AnimalFeeder is a subtype of DogFeeder (under "strictFunctionTypes")
// this is called "contra-variance"
// Although counter-intuitive at first glance, it ensures stronger type safety
declare let animalFeeder: AnimalFeeder
declare let dogFeeder: DogFeeder
// "contravariance"
dogFeeder = animalFeeder // Ok
animalFeeder = dogFeeder // Error when "--strictFunctionTypes"
// Ok when "strictFunctionTypes" is set to false, bi-variance
Насколько я понимаю: есть две разные проверки совместимости типов.
Для
const handler: RequestHandler = function (): boolean {
return false
}
Здесь происходит то, что функция возвращаемого типа boolean может быть назначена void, согласно Сравнение двух функций. Обратите внимание на пример в конце этого раздела и утверждение «Система типов обеспечивает, чтобы возвращаемый тип исходной функции был подтипом возвращаемого типа целевого типа». В данном случае void является подтипом логического значения.
Для
// error TS2322: Type 'boolean' is not assignable to type 'void'
function foo(): void {
return true
}
Здесь происходит сравнение типов данных, в отличие от первого случая. Таким образом, он жалуется на несоответствие типов, как и ожидалось.
пример: пусть x = () => ({ имя: "Алиса" }); let y = () => ({ имя: "Алиса", местоположение: "Сиэтл" }); х = у; // ХОРОШО
Я получаю это сейчас. Спасибо за ответ. Хотя я считаю, что "() => boolean" считается подтипом "() => void"
Вы имеете в виду, что логическое значение является подтипом пустоты?