According to this answer:
Using
void
instead means that forEach promises not to use the return value, so it can be called with a callback that returns any value
According to the TypeScript 3.0 release notes
...
unknown
is the type-safe counterpart ofany
. Anything is assignable tounknown
, butunknown
isn’t assignable to anything but itself andany
...
As much as I think about this, from these descriptions I can't find any single difference between those types.
I have also noticed that unlike unknown
, when void
is used as a type of a function argument, that argument can be omitted when calling the function, even though it is not marked as optional:
declare const x: (a: void) => void
x()
playground
While this behaviour is sometimes useful when working with generic code, it seems very strange. If void
is supposed to only ever be used in return types, why does it have this special behaviour, unlike every other type?
After a lengthy discussion with Aluan Haddad, my understanding is the following:
unknown
is a supertype of every other type. in other languages, this is mostly what the void
type is - anything can be assigned to it, but it can be used for nothing.
void
is a special type. under normal circumstances, it is only a supertype of undefined and no other type, not even null
.
This is what allows us to do any of the following:
const x: void = undefined;
(): void => undefined;
(): void => {};
but prevents us from doing any of:
const x: void = null;
const y: void = 5;
(): void => 5;
Unlike other types, though. void
has a special behaviour if used in an output position (as part of the return type): () => T
is a subtype of () => void
for any T
, which includes undefined
, null
and of course void
.
This enables doing things like:
const x: () => void = () => 5
the reason for void
existing and being used seems to be more historical than practical, given that it has existed before unknown
and that it interacts with the type-system differently than all other types (which also causes some weird things, like Promise<number>
not being a subtype of Promise<void>
).
The common way to decide between these types seems to be:
void
.unknown
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With