
Non-nullable types for TypeScript - muraiki
https://github.com/Microsoft/TypeScript/pull/7140
======
vog
Too bad that "strictNullChecks" is not the default behaviour. Because this is
the only really sane default, and is one the the things I loved so much in
strongly types languages such as OCaml, F# or Haskell. It reduces so make case
distinctions (and forgotten if/switch checks) to the only places where these
are really used.

Also, "strictNullChecks" is kind of optional security, which is almost always
a bad idea in the long run.

Maybe they did this for backwards compatibility? Are there any plans to make
"strictNullChecks" the default in the future?

~~~
geon
Since this is a brand new feature that isn't even accepted into the language
yet, it obviously can't be made default. If they decide to make it the default
behavior, there would need to be a period where the old bahavior is
depreciated and triggers warnings, but not errors.

I hope the --noImplicitAny option will become default.

~~~
mc808
One of the most touted features is "your JavaScript is already valid
TypeScript" (or pretty close), so I think they will keep the defaults so that
JS developers can just change the .js to .ts and be up and running with as
little friction as possible.

~~~
geon
Well, with the last release, typescriot supposedly can compile plain js.

[https://github.com/Microsoft/TypeScript/wiki/What%27s-new-
in...](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-
TypeScript#including-js-files-with---allowjs)

That should make it simple to treat ts more strict than js.

~~~
masklinn
> Well, with the last release, typescriot supposedly can compile plain js.

How does the ability to compile plain JS alter its goal of being a JS
superset?

~~~
jdmichal
Because it can compile plain JS using the rules present under plain JS, such
as nullable and undefined-able types by default, regardless of the rules it's
using to compile TS.

------
flatline
The Google Closure type system is much saner on this front already. A variable
of a declared type cannot be undefined. Nullable and non-nullable types are
distinct: primitives are non-nullable by default, with an option to make them
nullable (?string, ?number, etc.), and types deriving from Object are nullable
by default, with an option to make them non-nullable (!Object, !MyType, etc.)

Of course JavaScript itself does not have a notion of nullable types, so
touching any native API interfaces naturally leaves you with a bunch of
nullable types where you may well know the value will never be null, so you
are left trying to decide where to do nothing, where to add an assertion, and
where to add a conditional branch. This ambiguity comes through the Closure
API in many places that it would be nice to have a non-nullable type
guarantee, but I suppose the library has evolved over time and further must be
adaptable to a range of coding styles.

~~~
pka
> and types deriving from Object are nullable by default

So what's the point then?

~~~
munificent
You can flip the default. Back when I was using Closure Compiler, it was the
expected convention on my team to mark most of your type annotations non-
nullable.

------
cogware
I'm really impressed with how quickly the Typescript team is adding new
features - it feels like every time I check in on them they have something new
in the works that I really care about. Great work!

------
raquo
Looks like a good punch right into one of Facebook flow's advantages. Very
glad to see both static typing alternatives for JS evolving.

------
kbsletten
> A type guard for a dotted name has no effect if any part of the dotted name
> is the target of an assignment within the guarded code. For example, a type
> guard for x.y.z will have no effect if the guarded code contains any
> assignments to x, x.y, or x.y.z.

This is interesting to me because it is:

1) Unnecessarily conservative.

    
    
        let x = { y: { z: intOrNull() } };
        if (x && x.y && x.y.z) {
            const z = x.y.z;
            x.y = null;
            // z is of type "number?" when it could be "number"
        }
    

2) Not sound w.r.t. aliasing.

    
    
        let x = { y: { z: intOrNull() } };
        let x_ = x;
        if (x && x.y && x.y.z) {
            x_.y.z = null;
            const z = x.y.z;
            // z is of type "number" with a value of "null"
        }

------
ridiculous_fish
Really glad to see this. I encountered the use-before-declaration "feature" of
TS, and I just assumed it was a bug, which I filed. I was flabbergasted when I
was told it was by design, to match JavaScript.

The issue:
[https://github.com/Microsoft/TypeScript/issues/5822](https://github.com/Microsoft/TypeScript/issues/5822)

~~~
tom-lord
Funny how the conclusion is basically "Don't use `var`, use `let` instead" \-
even though almost all documentation/examples exclusively use the `var`
keyword!

~~~
egeozcan
From Ryan Cavanaugh's comment[1]:

> (...) there's already the let keyword available for those who want saner
> scoping rules. We should definitely update the docs to use let everywhere,
> though.

[1]:
[https://github.com/Microsoft/TypeScript/issues/5822#issuecom...](https://github.com/Microsoft/TypeScript/issues/5822#issuecomment-161079139)

~~~
tom-lord
Yes, however that was 3 and a half months ago -- and as far as I can tell,
there's been no movement towards doing so.

~~~
RyanCavanaugh
It's been fixed for a few months in the Handbook repo
([https://github.com/Microsoft/TypeScript-
Handbook/pull/119/fi...](https://github.com/Microsoft/TypeScript-
Handbook/pull/119/files)), but the new updated Handbook hasn't been pushed to
the website yet.

