неожиданное поведение компилятора typescript при использовании интерфейса функции с void

#typescript #interface

#typescript #интерфейс

Вопрос:

Если я определю интерфейс функции с типом возвращаемого значения number, компилятор предупредит меня

 
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

 

Ответ №1:

Мое понимание: существуют две разные проверки совместимости типов.

Для

 const handler: RequestHandler = function (): boolean {
    return false
}
 

Здесь происходит то, что функция возвращаемого типа boolean присваивается void в соответствии со сравнением двух функций. Обратите внимание на пример в нижней части этого раздела и утверждение «Система типов обеспечивает, чтобы возвращаемый тип исходной функции был подтипом возвращаемого типа целевого типа». В данном случае void является подтипом boolean .

Для

 // error TS2322: Type 'boolean' is not assignable to type 'void'
function foo(): void {
    return true
}
 

Здесь происходит сравнение типов данных, в отличие от первого случая. Таким образом, он жалуется на несоответствующие типы, как и ожидалось.

Комментарии:

1. Вы имеете в виду, что boolean — это подтип void ?

2. пример: пусть x = () => ({ имя: «Алиса» }); пусть y = () => ({ имя: «Алиса», местоположение: «Сиэтл» }); x = y; // OK

3. Теперь я все понимаю. Спасибо за ответ. Хотя я считаю, что «() => логическое значение» рассматривается как подтип «() => void»