5

I don't understand the reasoning behind non nullable types and Typescript's strictNullChecks flag. I always set the value of a variable to null when I am sure I am done with it to release it from memory and the GC can collect it. My tests have shown that it speeds up the execution of the JavaScript code by many times, especially in long, and deep loops. Is this a bad practice? Should some types of variables be set to null and not others?

4
  • 1
    just out of curiosity, could you share the tests you're talking about? Commented Sep 28, 2019 at 10:17
  • The tests I referred to were basically running some code on an older model smart phone and crashing it with an out of memory code, then tweaking the code until it would run again. Consequently the code also ran ~4X faster in a desktop browser (Firefox) as well, probably by avoiding the GC. The code was parsing several MB of CSV text to JSON and storing it in a database. Quite complicated to show here Commented Sep 28, 2019 at 10:28
  • 2
    My advice if you're only using null to free up memory (hey, you're the boss): turn on --strictNullChecks, declare your variables as non-nullable (e.g., let x: string = "hello"; and then if you must set a variable to null when you're done with it, lie to the compiler about it (e.g., x = null!; where the ! operator is a non-null assertion); safe enough if you're really not using it anymore. Happy to turn this into an answer if it meets your needs. Good luck! Commented Sep 29, 2019 at 0:21
  • Thanks @jcalz x = null!; fixes all my errors with a simple find and replace while still allowing the strictNullChecks flag to be used. It probably doesn't answer the entire question but was a super tip! Commented Sep 30, 2019 at 7:15

2 Answers 2

3

The reasoning is to prevent some run-time errors including console.log(null.printWhyNullIsBad()); by catching those errors at the compilation time while assuming that people who write loops so deep and so nested that it stretches the modern JS garbage collectors to their limits can write that kind of code in C/C++ and run it using WebAssembly.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, so basically I'm biting off more than JavaScript can chew. I'm not a C/C++ developer, but I think in those languages where there is no GC you would be setting unused values to null when done with them anyways, though likely would be a much better approach if I knew those languages
I understand that in JS setting to null a variable (which is a handle to an object which in turn is an opaque pointer to GC memory) doesn't actually free the memory. It serves as a hint for GC which otherwise might collect it later, during subsequent garbage collection rounds. And no, that's not how it works in C/C++. For stack based objects you don't do anything because stack gets reused/overwritten when a function returns. For heap based objects you have to explicitly allocate memory and then you have to explicitly deallocate it unless you use C++ helpers that help you with deallocation.
1

In most cases you don't have to delete variable values yourself. It may be a design flaw. Also note that if you want to delete an object property value, it may be more consistent to use that:

    delete myObject.attr;  // set 'undefined'

I don't understand the reasoning behind non nullable types and Typescript's strictNullChecks flag.

To understand the logic behind, check this sample:

// strictNullChecks: false

interface Sample {
  color: string;
  width: number;
}

function doSomething(sample: Sample): Sample {
  if(sample.width > 10) {
    return null;
  }
  return sample;
}

const first: Sample = {
  color: 'red',
  width: 15
};

const second: Sample = doSomething(first);

console.log(second.width);  // Uncaught TypeError: Cannot read property 'width' of null

Playground

This code compiles only without strictNullChecks flag. In this context when the code runs we have a beautiful error: Uncaught TypeError: Cannot read property 'width' of null.

Check the function doSomething. It returns a Sample type, but without the flag we can return null. The problem here is that when we call this function, the value returned will be manipulated as a Sample => There is a inconsistence between the type and its real value type. It's a huge cause of errors.

I like to think that TS typings must reflect at the best real types of values.

4 Comments

I understand your answer is meant to show a possibility of unintentional error with TS. The code won't compile unless you change it to: function doSomething(sample: Sample): Sample|null { to indicate you are happy with the function returning null.
@deceze Right ! I edited my post, it works only for object properties.
@winwiz1 yes, this code will compile only without strictNullChecks flag. It's to answer the first interrogation of the author, "why this flag ?".
Likely is a design flaw of a rookie developer :) However, setting the value to null does seem to fix my problem with the GC in this case. Maybe I need to tell Typescript that I intended to do that so it doesn't throw all these errors, or just turn off the flag

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.