Подтвердить что ты не робот

TypeScript: тип возврата void преобразован в любой тип?

Кажется, я не могу понять, почему следующий код не вызывает ошибку:

var rg: {(): void;}[] = [];
rg.push(function():string {return "";})

Я четко заявляю, что тип должен быть массивом функций, возвращающих void, но я нажимаю туда функцию, которая возвращает string, и все же компилятор не жалуется. Если я изменил определение rg на

var rg: {():number;}[] = [];

Компилятор начинает жаловаться.

Является ли это ошибкой или как работает возвращаемый тип void (т.е. что-либо происходит, если используется void, в основном делая его таким же, как тип возврата any)?

4b9b3361

Ответ 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'