Ответ 1
Это по дизайну (я объясню, почему это хороший дизайн в ближайшее время). Спектр говорит (в разделе 3.6.3, сокращенно для ясности):
Тип S присваивается типу T, а T можно назначить из S, если выполнено одно из следующих условий:
S и T - типы объектов, и для каждого члена M в T выполняется одно из следующих условий:
M - это подпись вызова, конструкции или индекса, а S содержит вызов, конструкцию или подпись индекса N, где
- тип результата M является Void, или тип результата N присваивается типу результата M.
В этом случае мы тестируем, если () => string
назначается () => void
. Таким образом, либо string
должен быть назначен void
(это не так), либо void
должен быть void
(это).
По сути, правило здесь вам разрешено отбрасывать возвращаемое значение, что согласуется с тем, как, например, С++ рассматривает void
в разрешении шаблона.
function decrementWidgetHeight(w: Widget): number {
// ... returns the new height of the widget
}
function applyToManyWidgets(w: Widget[], change: (x: Widget) => void): void {
// for each widget in the array, apply 'change' to it
}
// Later...
applyToManyWidgets(widgetsToShorten, decrementWidgetHeight); // Should be allowed?
Когда мы ограничиваем тип change
равным (widget) => void
, мы делаем это так, чтобы вы могли передать decrementWidgetHeight
в качестве второго аргумента, даже если он имеет возвращаемое значение, но все же убедитесь, что когда мы напишите тело applyToManyWidgets
, мы случайно не используем возвращаемое значение change
где-нибудь.
Обратите внимание, что void
по-прежнему отличается от any
, потому что это недопустимо:
function f() { }
var x = f(); // Disallowed, f() is of type 'void'