Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript: void return type converted to any type?

Tags:

I seem to be not able to comprehend why the following code does not raise error:

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

I clearly state that the type should be an array of functions that return void, however I push there a function that returns a string and yet the compiler does not complain. If I change the definition of rg to

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

The compiler starts to complain.

Is this a bug or is it how the void return type is supposed to work (i.e. anything goes if void is used, basically making it the same as return type any)?

like image 956
Peter StJ Avatar asked Oct 06 '12 16:10

Peter StJ


People also ask

Can void functions return anything?

A void function can returnA void function cannot return any values. But we can use the return statement. It indicates that the function is terminated. It increases the readability of code.

What does () => void mean TypeScript?

Introduction to TypeScript void type The void type denotes the absence of having any type at all. It is a little like the opposite of the any type. Typically, you use the void type as the return type of functions that do not return a value.

What if the return type is void?

So what am I supposed to return if the return type of a function has to be Void ? Use return null . Void can't be instantiated and is merely a placeholder for the Class<T> type of void .

Can I use return for a method of the return type void?

Any method declared void doesn't return a value. It does not need to contain a return statement, but it may do so.


1 Answers

This is by design (I'll explain why it's good design shortly). The spec says (in section 3.6.3, abridged for clarity):

A type S is assignable to a type T, and T is assignable from S, if one of the following is true...

  • S and T are object types and, for each member M in T, one of the following is true:

    • M is a call, construct or index signature and S contains a call, construct or index signature N where

      • the result type of M is Void, or the result type of N is assignable to that of M.

In this case, we're testing if () => string is assignable to () => void. So either string has to be assignable to void (it isn't), or void has to be void (it is).


In effect, the rule here is you are allowed to throw away the return value, which is consistent with how e.g. C++ treats void in template resolution.

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? 

When we constrain the type of change to be (widget) => void, we're making it so that you can pass decrementWidgetHeight as the second argument even though it has a return value, but still making sure that when we write the body of applyToManyWidgets, we don't accidentally use the return value of change anywhere.

Note that void is still different than any because this is unallowed:

function f() { } var x = f(); // Disallowed, f() is of type 'void' 
like image 163
Ryan Cavanaugh Avatar answered Sep 27 '22 22:09

Ryan Cavanaugh