Esto es por diseño (explicaré por qué es un buen diseño en breve). La especificación dice (en la sección 3.6.3, abreviada para mayor claridad):
A type S is assignable to a type T, and T is assignable from S, if one of the following is true...
En este caso, estamos probando si es asignable a () => string
() => void
. Entonces, o bien string
tiene que ser asignable a void
(no lo es), o void
tiene que ser void
(es).
De hecho, la regla aquí es se le permite tirar el valor de retorno, lo cual es consistente con la forma, por ejemplo, C++ trata void
en resolución de plantilla.
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?
Cuando limitamos el tipo de change
ser (widget) => void
, lo estamos haciendo para que pueda pasar decrementWidgetHeight
como segundo argumento a pesar de que tiene un valor de retorno, pero sigue asegurándose de que cuando escriba el cuerpo de applyToManyWidgets
, no utilizamos accidentalmente el valor de retorno de change
en ninguna parte.
Tenga en cuenta que void
sigue siendo diferente de any
porque esto es inadmisible:
function f() { }
var x = f(); // Disallowed, f() is of type 'void'
he [interpuso una cuestión] (http://typescript.codeplex.com/workitem/139). –