13

The TypeScript Coding Guidelines state

Use undefined. Do not use null

Having just read another article on ECMAScript, which advocates for null over undefined, I was wondering whether Microsoft’s or the TypeScript team’s rationale is known for this decision?

Matthew Layton
  • 39,871
  • 52
  • 185
  • 313
  • 4
    As stated in the guidelines, it is chosen for team consistency for that project, it is not meant as prescriptive guideline for typescript community to follow. So that's their rationale, 'consistency'. – Rosdi Kasim Apr 10 '18 at 06:34
  • @RosdiKasim consistency is all well and good, however I was wondering if there was any technical rationale? The other article (now in the post) seems to have more of a technical stance. – Matthew Layton Apr 10 '18 at 06:43

3 Answers3

16

No rationale is necessary for guidelines, the requirement could be chosen at random in order to keep the code base consistent.

As for this guideline, undefined takes more characters to type but doesn't need to be explicitly assigned to nullable variable or property:

class Foo {
  bar: number|undefined;
}

function foo(bar: number|undefined) {}

vs.

class Foo {
  bar: number|null = null;
}

function foo(bar: number|null = null) {}

Also, it's less convenient to check the type of null value at runtime because typeof val === 'object' for both null and object value, while it's typeof val === 'undefined' for undefined.

There is relevant TSLint rule that addresses this concern, no-null-keyword.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    That's the best answer. I would like to add that, in early versions of JavaScript, an argument against `undefined` was that it [could be reassigned](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/undefined#Description) as a global variable. But in 2018, there is no downside to `undefined`. – Paleo Apr 10 '18 at 09:13
  • @Paleo That's true. This would cause TS compilation error any way. – Estus Flask Apr 10 '18 at 09:24
  • But `val === null` is easier than `typeof val === 'undefined'`. And you may also use `val == null` if you like. So I don't think convenient of type checking is a reason. – tsh Jan 10 '19 at 02:22
  • @tsh It could be `val == null` or `val === undefined` for undefined as well. I meant cases where `typeof` checks are needed (e.g. `val` is potentially not defined) and an object is expected. That `typeof val === 'object'` for `null` results in ambiguity and requires additional check. – Estus Flask Jan 10 '19 at 06:59
4

I made some research few months ago and I came out with the fact that undefined must be prioritize using tslint rule 'no-null-keyword'.

I tried to change my codebase and I had some issues. Why? Because I'm using an API that return null for empty fields.

I struggled because of the tslint triple-equals rule.

if (returnedData === undefined) // will be false because returnedData is null

Which let you 2 options:

1) Add some parameters to your triple-equals rules.

"triple-equals": [true, "allow-null-check"] and do If (returnedData == null)

allow-null-check allow "==" for null

2) Use If (returnedData) instead but it checks if null/undefined/empty string or a zero

The Segfault
  • 939
  • 1
  • 10
  • 23
  • _"but it checks if `null` OR `undefined`"_ ... or an empty string or a zero. But a test `if (returnedData)` remains a good test if you are sure that the value is an object or null/undefined, never a scalar value. – Paleo Apr 10 '18 at 09:25
  • 1
    @Paleo indeed, that's why I go first option, i'll add – The Segfault Apr 10 '18 at 10:09
  • I think the first option (with `== null`) will have the same result: `0`, `""`, `false`, `null` and `undefined` are all `==`. The operator `==` is just a bad practice. The second option is better. – Paleo Apr 10 '18 at 10:53
  • 1
    @Paleo https://gyazo.com/a90c339be646f49170bafd58cdc625df first option is taking undefined or null second is taking all – The Segfault Apr 10 '18 at 11:46
  • I didn't know. Thank you. – Paleo Apr 10 '18 at 13:33
2

Why use null over undefined?

In javascripts objects are dynamic without any type information. therefor:

var person
person.namme

could either be a misspell or it could be the name property. If you use undefined as null you won't know when debugging if:

  • variable/property is not initialized yet, or
  • you miss typed the property name.

Therefor null is preferable over undefined, you defer between:

  • forgot to initialize property and
  • wrong property used.

That said: Typescript is typed. thus the following code:

var person
person.namme

would result in a type error at compilation. Thus null in that sense is no longer needed.

That said, i still prefer null over undefined.

Joel Harkes
  • 10,975
  • 3
  • 46
  • 65