Hacker News new | ask | show | jobs
by jraph 1226 days ago
I've thought of something like that before for js. For this precise case, I guess the directive could forbid the use of typeof, or its use on null (and make it a runtime error). And your code ought to not accept values returned by typeof from foreign code, or to be careful with the "object" case.

I don't think it can be a complete solution for making typeof return "null" for null for two reasons.

1) If you call f(typeof v) where f is defined in a module written in a different version, you are screwed. Contrived but within spec and we all know https://xkcd.com/1172/ (if you didn't, now you do).

2) Moreover, old engines will ignore your directive and behave differently (return "object" instead of "null"), so now your code is incorrect depending on what engine runs it.

In the end, it could as well be a linter rule that forces you to test v === null before calling typeof v and I think it would be the best option. If you care about this kind of stuff, you are probably already using a linter. The same kind of tool that complains about "==", which sets the same kind of traps, and you don't need to wait for something wrong to happen during execution, it's already warned statically before even running the code.

2 comments

(1) Yes this makes interoperability hard. However, `typeof` is generally used to test the type of value. It is unlikely to pass its value to a function

If you use a function declared in a module with a distinct edition, you have to comply to its contract. And its contract certainly state that "null" is not a valid value to pass through.

Moreover, a type checker or linter could error/warn about this.

(2) You are right.

Another solution might be to introduce a new keyword:

  ```js
  use "edition2023"
  ```
Old browser could thus crash. In the same way that they did for ESM.

  In the end, it could as well be a linter rule that forces you to test v === null
  before calling typeof v and I think it would be the best option. If you care
  about this kind of stuff, you are probably already using a linter.
Yes. However, this does not allow performing more advanced optimizations. Bundlers, Transpilerss minifiers, and compilers must handle all this complexity making some optimizations unsafe or even impossible.