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

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


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

Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
1
0
113
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Насколько я понимаю: есть две разные проверки совместимости типов.

Для

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
}

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

Вы имеете в виду, что логическое значение является подтипом пустоты?

Jake Zhang 14.12.2020 03:15

пример: пусть x = () => ({ имя: "Алиса" }); let y = () => ({ имя: "Алиса", местоположение: "Сиэтл" }); х = у; // ХОРОШО

ABOS 14.12.2020 12:48

Я получаю это сейчас. Спасибо за ответ. Хотя я считаю, что "() => boolean" считается подтипом "() => void"

Jake Zhang 15.12.2020 03:51

Другие вопросы по теме