Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

void as a type of an argument of a generic function in TypeScript

Tags:

typescript

It is possible to specify void as a type parameter for generic function in TypeScript. And it works fine for return values of functions. However when void is a type of an argument it's not that clear what value can be used for it. Is there a way to specify a parameter for an argument of the void type? If no, why is it possible to declare such a function?

like image 798
Trident D'Gao Avatar asked Jan 14 '14 18:01

Trident D'Gao


Video Answer


4 Answers

From the TypeScript specification:

NOTE: We might consider disallowing declaring variables of type Void as they serve no useful purpose. However, because Void is permitted as a type argument to a generic type or function it is not feasible to disallow Void properties or parameters.

like image 69
C Snover Avatar answered Oct 23 '22 04:10

C Snover


It is possible to use void as a type argument, but you shouldn't use it as a type.

In fact, although you may be able to use it in a type annotation currently, it is impossible to assign a value:

var x: void = ???; // cannot supply a value

The use of void as a type argument is illustrated below:

class Example<TReturn> {
    process(func: () => TReturn) {
        return func();
    }
}

The type argument in this class is used to specify the return type of a function. That means that I may wish to specify that the function will have the void type. So it must be allowed as a type argument.

var example = new Example<void>();

Now when I write the call to example.process, auto-completion will tell me that the argument I pass needs to satisfy the following type:

func: () => void

And it will also tell me that example.process itself is void in this case.

The intention isn't for void to ever be used to annotate a type, but because there are valid reasons to allow it as a type argument it isn't checked currently. It means you can create something invalid, but you'd be hard pressed to use it:

class Example<T> {
    process(func: T) {
        // if T is void, this is all wrong
    }
}

var example = new Example<void>();

In this invalid example (which doesn't show any errors) you wouldn't be able to write a call to example.process because you couldn't pass a valid argument.

like image 32
Fenton Avatar answered Oct 23 '22 05:10

Fenton


A useful use for void is when you want to make a parameter optional. Angular uses this a lot with RxJS Subject<T> when emitting events and there's no useful type for the event.

The signature for Subject<T>'s next function is :

next(value?: T)

You can create a Subject<void> which makes the value parameter forbidden:

new Subject<void>().next() // ok

new Subject<void>().next(true) // not allowed

as opposed to non-void where you get

new Subject<boolean>().next(true)

Not sure exactly which TS version this became possible.

like image 30
Simon_Weaver Avatar answered Oct 23 '22 05:10

Simon_Weaver


It turned out it's very easy to get a value of void. Although technically it is still the undefined value, but TypeScript believes it's of the type void which is exactly what we need:

var voidValue = (function () { })();
like image 25
Trident D'Gao Avatar answered Oct 23 '22 05:10

Trident D'Gao