#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»