Why does TypeScript have both `void` and `undefined`?

Ryan Cavanaugh

In TypeScript, you can annotate a function as returning void:

function fn1(): void {
  // OK
}

function fn2(): void {
  // Error
  return 3;
}

You can also annotate a function to return undefined:

function fn3(): undefined {
  // OK
  return;
}

function fn4(): undefined {
  // Error
  return 3;
}

So it seems that if you call a function returning void, you'll always get back the value undefined. Yet you can't write this code:

function fn5(): void {
}
let u: undefined = fn5(); // Error

Why isn't void just an alias for undefined? Does it need to exist at all?

Ryan Cavanaugh

void has special meaning in function return types, and is not an alias for undefined. Thinking of it this way is very wrong. Why?

The intent of void is that a function's return value will not be observed. This is very different from will be undefined. It's important to have this distinction so that you can properly describe functions like forEach. Let's consider a freestanding version of Array#forEach, written with undefined instead of void in the callback return position:

declare function forEach<T>(arr: T[], callback: (el: T) => undefined): void;

If you tried to use this function:

let target: number[] = [];
forEach([1, 2, 3], el => target.push(el));

You'd get an error:

Type "number" is not assignable to type "undefined"

This is a correct error - you said you wanted a function that returned the value undefined, but you actually provided a function that returned the value number because that's why Array#push returns!

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

declare function forEach<T>(arr: T[], callback: (el: T) => void): void;
let target: number[] = [];
// OK
forEach([1, 2, 3], el => target.push(el));

Why not just use any ? If you're actually the one implementing forEach, you really don't want that - having an any floating is a dangerous thing that can defeat typechecking very easily.

The corollary to this is that if you have some function expression whose return type is void, you cannot say with any certainty that the result of invoking that function is undefined.

Again, void is not an alias for undefined and an expression of type void may have any value, not just undefined

In a function body whose return type is explicitly listed as void, TypeScript will stop you from "accidently" returning a value, even though this wouldn't create a type system violation. This is helpful for catching bugs that appear from a refactoring:

// Old version
function fn(arr: number[]): void {
  const arr1 = arr.map(x => {
    return 3;
  });
}

// New version
function fn(arr: number[]): void {
  for (const x of arr) {
    // Oops, meant to do something else
    return 3;
  };
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

why does javascript have both null and undefined?

From Dev

Why does the standard have both seekpos() and seekoff()?

From Dev

Why is it possible to have both numeric and string index signatures for an interface in TypeScript?

From Dev

Why does LiveScript use 'void 8' for undefined values?

From Dev

Why does LiveScript use 'void 8' for undefined values?

From Dev

Why does HttpClientHandler have both Proxy and UseProxy properties?

From Java

Why does Stream.Builder have both add and accept methods?

From Dev

Why does Rust have both call by value and call by reference?

From Dev

Why does Python have both a module and a class called datetime?

From Dev

Why does Swift have both NSDictionary and Dictionary classes?

From Dev

Why does Linux need to have both `/dev/cdrom` and `/media/cdrom`?

From Dev

Why does both the multiple method program have different results

From Dev

Why have both /mnt and /media?

From Dev

What does 'void' in typescript mean?

From Dev

TypeScript UMD both 'module' and 'define' are undefined

From Dev

TypeScript UMD both 'module' and 'define' are undefined

From Java

Why Does OAuth v2 Have Both Access and Refresh Tokens?

From Dev

Why does Mongoose's JavaScript have both a return and a callback in the same line?

From Dev

Why does SCSI standard allow a device to have both multiple "ports" and multiple "logical units"?

From Dev

Why does the Google App Engine NDB datastore have both "—" and "null" for unkown data?

From Dev

Why does an MBR partition table entry have its starting sector as both CHS and LBA?

From Dev

Why does Linux show both more and less memory than I physically have installed?

From Dev

Why does SCSI standard allow a device to have both multiple "ports" and multiple "logical units"?

From Dev

Why does Skype obsolete so many Java packages and how can I have both?

From Dev

Why does this split both elements?

From Dev

Why does the Void class exist?

From Dev

Why does the Void class exist?

From Dev

Why does java use void?

From Java

Why in TypeScript an array element accessed by index doesn't have "undefined" in its type?

Related Related

  1. 1

    why does javascript have both null and undefined?

  2. 2

    Why does the standard have both seekpos() and seekoff()?

  3. 3

    Why is it possible to have both numeric and string index signatures for an interface in TypeScript?

  4. 4

    Why does LiveScript use 'void 8' for undefined values?

  5. 5

    Why does LiveScript use 'void 8' for undefined values?

  6. 6

    Why does HttpClientHandler have both Proxy and UseProxy properties?

  7. 7

    Why does Stream.Builder have both add and accept methods?

  8. 8

    Why does Rust have both call by value and call by reference?

  9. 9

    Why does Python have both a module and a class called datetime?

  10. 10

    Why does Swift have both NSDictionary and Dictionary classes?

  11. 11

    Why does Linux need to have both `/dev/cdrom` and `/media/cdrom`?

  12. 12

    Why does both the multiple method program have different results

  13. 13

    Why have both /mnt and /media?

  14. 14

    What does 'void' in typescript mean?

  15. 15

    TypeScript UMD both 'module' and 'define' are undefined

  16. 16

    TypeScript UMD both 'module' and 'define' are undefined

  17. 17

    Why Does OAuth v2 Have Both Access and Refresh Tokens?

  18. 18

    Why does Mongoose's JavaScript have both a return and a callback in the same line?

  19. 19

    Why does SCSI standard allow a device to have both multiple "ports" and multiple "logical units"?

  20. 20

    Why does the Google App Engine NDB datastore have both "—" and "null" for unkown data?

  21. 21

    Why does an MBR partition table entry have its starting sector as both CHS and LBA?

  22. 22

    Why does Linux show both more and less memory than I physically have installed?

  23. 23

    Why does SCSI standard allow a device to have both multiple "ports" and multiple "logical units"?

  24. 24

    Why does Skype obsolete so many Java packages and how can I have both?

  25. 25

    Why does this split both elements?

  26. 26

    Why does the Void class exist?

  27. 27

    Why does the Void class exist?

  28. 28

    Why does java use void?

  29. 29

    Why in TypeScript an array element accessed by index doesn't have "undefined" in its type?

HotTag

Archive