Announcing TypeScript 2.0 Beta
blogs.msdn.microsoft.com
blogs.msdn.microsoft.com
let lowerCased = strs!.map(s => s.toLowerCase());
I'm not a big fan of this, it's really starting to change JS semantics. It's not just type annotations anymore + ES6 . It's starting to look like its own language. Some might like that, I do not.They should be a bit more cautious before introducing these features. What if Ecmascript in the future uses ! as an operator for a totally unrelated purpose ? It's like decorators, they are not in the spec, there is no plan yet to officially had them to the spec, yet, Angular2 which is written in Typescript abuse them. What if in 2 years they are introduced in ES2019 with different semantics ? How Typescript is going to handle that too ?
If in the unlikely worst case scenario the TS team drops/renames the ! syntax at some point, given that these are compile time checks, you will just manually go through a list of compile time errors and fix the issues one by one.
More likely scenarios:
- They will make the change in a backwards-compatible way
- They will release a jscodeshift script to do the upgrade for you
- Etc.
I think the general idea of adding syntax outside of declarations really rubs me the wrong way, but perhaps it shouldn't.
In my experience, the overhead caused by TypeScript is far outweighed by benefits in tooling and confidence that my code works (mostly) after refactors.
Even so, I've been pretty impressed with the TypeScript teams ability to manage this kind of change an uncertainty and keep up with and move closer to standard JavaScript where they have been differences.
Specifically regarding the `!` operator* , to convert to standard JavaScript just remove the `!` operator, like you would remove a cast or type annotation. It's still within the TypeScript spirit to me.
* I personally would have rather seen it either be a type of cast (maybe `<!>strs.map(...);`), or add a null-safe property accessor: `strs?.map(...)` which doesn't assert that `strs` is non-null, but makes the expression null-safe, returning null if `strs` is null.
let x = (id: number, name?: string) => { return; };
Is it abuse to use interfaces as well? They are not present in vanilla JS.How about React's move away from React.createClass({}) to ES6 classes extending React.Component? Do they abuse classes?
Async/await is coming too and it will turn JS on its head, does eschewing callbacks for async functions also count as abuse?
I won't even get into generics as that's a whole different can of worms.
Microsoft and the TS team have issued a mandate that TypeScript will always be a superset of EcmaScript and if ES2019 includes decorators that are incompatible with TypeScript's then it will be addressed at that time.
TypeScript was never meant to be just type annotations+ES6, there is Flow[1] for that.
hmm, it would make more sense if it was written like that
> let x = (id: number, name: string?) => { return; };
But I guess it's more or less ok. But I definitely feel inconfortable with the ! .
> How about React's move away from React.createClass({}) to ES6 classes extending React.Component? Do they abuse classes?
I don't use React.
> Async/await is coming too and it will turn JS on its head, does eschewing callbacks for async functions also count as abuse?
The probability is higher for ES to implement async/await than the ! operator. The former is a safe bet, the latter isn't, by a long shot.
> Microsoft and the TS team have issued a mandate that TypeScript will always be a superset of EcmaScript and if ES2019 includes decorators that are incompatible with TypeScript's then it will be addressed at that time.
It means that language will break. Not very good if you write large TS codebases today.
> TypeScript was never meant to be just type annotations+ES6, there is Flow[1] for that.
That's your opinion. I'm not interested in Flow.
Ultimately TS is successful because it more or less looks like Action Script 3/ES4/JScript.net and javascript itself. Make it too Alien and the people who refused to use Coffee script because of its semantics will not want to use TS. And FYI I use TS today. I may reconsider that.
> hmm, it would make more sense if it was written like that
> > let x = (id: number, name: string?) => { return; };
> But I guess it's more or less ok. But I definitely feel inconfortable with the ! .
I think the point is that typescript currently supports the shown optional parameter syntax, JS could be extended in a conflicting way to that as well.
In the end, if you are using something that extends JS and you expect that any code you write will continue to work in future versions and that the tool will be altered to stay as close to the standard JS as possible as extended features are incorporated into vanilla JS, you're most likely deluding yourself. Much better to accept that the tool should either try to match vanilla JS, in which case you must accept that you may need to refactor to update occasionally, or that it will eventually diverge, but your code will continue to work, and choose a tool that implements whatever strategy is acceptable to you.
Curious: Why not?
It seems to have interprocedural type inference, which is really cool, but I'm not sure that's a feature I'd even want in Typescript, since I feel like it would make code less self documenting.
Overall it seems like there is more community support for Typescript than Flow, which is essentially just group inertia, but it makes me not want to switch.
|>
<|
combinedFn = function1 >> function2
etc... Though the last is mostly handled with fat-arrow syntaxhttps://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...
The exclamination is a forced cast to another type, just like "x as otherType". So this is still in the same category.
But since its Facebook, its completely fine that they're trying to co-opt standards. No problem at all.
> It's not just type annotations anymore + ES6
How not?
! is just an inline type coercion.
> What if Ecmascript in the future uses ! as an operator for a totally unrelated purpose ?
This seems unlikely because ! is already an operator in JS.
But really, this argument could be made against any operator TS uses. What if ES introduces : as an operator? Or if they introduce some sort of ambiguity with the other myriad type definitions? This is not a new issue, and you shouldn't let null checks drive you away from the language.
In any case, both null checks and decorators are behind flags. The decorators flag is literally called "experimental decorators". So it's not like the TS team is pretending that it's going to be stable forever.
Are you sure about that? It sounds more like a signal to the compiler to "trust me, I know what I'm doing" and would blow up if you passed undefined anyway. Maybe the author didn't explain it very well. That is, not a type coercion so much as a hint to not bother checking this access.
At least that's what it looks like. I've never used typescript or I'd test it right now. I'm on my phone and haven't tried it.
(Edit: my answer didn't quite make sense! It's different since without ! it compiles as an error because, in this case, you can't map over undefined. With !, it just ignores that possibility although it could still happen. The compiler cannot verify all run time possibilities since your sum type says it really can be undefined.)
(Re edit! Verifying the types vs skipping that verification is not the same thing as coercing the types)
let lowerCased = (s : string[] | undefined) => s!.map((str : string) => str.toLowerCase());
console.log(lowerCased(['A','B']));
console.log(lowerCased(undefined)); //boom!
It doesn't coerce anything. All it does is let the code pass without error. "s!.map" and "s.map" compile to the exact same Javascript code, which means there is no type coercion going on. Are you sure you know what type coercion is? The first log prints out fine and the second blows up, which proves that undefined isn't being coerced to a string[]. If that was the case, the resulting JS would be checking for undefined and probably creating an empty array.As to the additional checks for non-null types, I'd say that async/await would be far more welcome at this point... it's one of the few reasons that those using TS are still running their output through babel after.
Personally, I'm not a fan of TS, but can see why others would like it... I'm pretty good with ES2016 + Stage-1 via Babel...
This will greatly facilitate a more functional style of programming.
(Aside: I'm moderately disappointed the 'fabulousness' was not in my Chromium's spell checker dictionary. It is now.)
Also, sorry if you meant something else, «fabulousness» is a very subjective term, not unlike «elegant» (as in «elegant code»), and because it does not have a specific and commonly shared meaning (what is fabulous to you may not by fabulous to others), it's not something I'm very comfortable discussing, although I think I have understood what you meant by it, but with a low level of certainty.
This is great. However, it would be nice to know if this feature will become opt-out in the future instead of opt-in. In theory, if you're a TS user (as opposed to JS) it's because you want these nice features _by default_.
If you pay too much attention to keeping legacy code 'alive' you end up complicating matters with either compiler-flags all over the place or redundant API's i.e win32 api (old+new+newer versions of the same function).
Let's say I want to use the new type system, but some library I depend on hasn't been updated. If I enable the new type system, I'll get both false positives and negatives when type checking.
If a library writer updated to the new type system, they'd break compatibility with callers that haven't updated. The safest option would be to maintain two almost-identical copies of the library -- one for the old type system and one for the new one.
A better option would be to allow specifying the type system mode at the top of each file (like "use strict"). This allows me to use the new type system even if not all my libraries have updated yet. This also allows libraries writers to use the new type system features without breaking existing users.
Good point, but then how about an opt-out warning (instead of error)?
(according to https://github.com/Microsoft/TypeScript/pull/7140)
Sounds like Flow. Curious to see how they converge/diverge over time.
I know there are people who hate the tooling spaghetti that modern JS development involves, but I appreciate that I can plug Flow into a babel/webpack stack and have it just do the error checking. I also have high hopes for things like tree shaking and its ilk that control flow analyzers (Flow, and now TypeScript) will bring to JS going forward.
I'm sure you could have Babel just do the experimental transforms and pipe the result into TypeScript, but having two separate sugar/transformation systems seems not-great.
Then again, I was hoping the same thing with webpack, then we get rollup, etc... it's interesting, though hard to make some choices while staying pragmatic.
They're really starting to put their efforts behind control flow analysis. They already did a little bit of that before (with type guards), but it seems they're really serious about it now. 2.0 also adds verification for unused declarations with `--noUnusedLocals` and `--noUnusedParameters`, so I want to believe they're moving towards tree shaking.
This is the first filter I check when I am deciding to learn a programming language these days. Almost all real world code I saw have had random null checks everywhere.
That's the one killer feature I'm missing.
Typescript has been nothing short but amazing though!
The only thing that might be time-consuming is setting your paths if you don't already have a plan for keeping things separate.
I've been slowly switching away from Coffeescript to Typescript and have been mostly happy with it.
Only thing I still struggle with is grappling the namespace/modules mess in Javascript that's been inherited by Typescript.
Does this mean that using Typings is no longer necessary, or is there some additional benefits that Typings still offers?
0. https://blogs.msdn.microsoft.com/typescript/2016/06/15/the-f...
That last part is in need of change because you're not supposed to concatenate commonJS. So how have you been delivering your code to the browser?
If that seems too much, the other option is to output the compiled code as AMD modules [1]. But I have not tried it myself. Regardless, the option is still there, and, IMO, it seems like a painless transition away from concatenation.
Webpack can then analyse your ES6 module tree and perform "tree shaking", a form of dead code elimination where unused modules are excluded from the compiled bundle. This will become increasingly useful as more libraries are authored in ES6 / TypeScript, as it will allow you to import the whole of a framework like Angular or React, but only ship the parts of it that you actually use in your application.
I have projects that configure SystemJS to use TS itself as the only ES2015/TS transpiler (and thus no emit necessary in development, let the browser compile it, which makes for a fairly nice rebuild). You can even use TS directly as your bundler in this case if all you want to bundle are your TS sources as it supports the SystemJS registration format.
I also have some projects that still use Babel as a transpiler and TS emitting ES2015+JSX to it (still in the JSPM/SystemJS stack). I've particularly needed this because TSX is great but it's support for non-React TSX emission is still somewhat lacking in my opinion versus what easily works in Babel.
Always be explicit, like var foo=-1; if(foo!=-1) instead of only var foo; if(foo). It will also help the optimizer
So true. Happy to see this. Makes me think of how Rust works.
http://justinfagnani.com/2015/12/21/real-mixins-with-javascr...
Might provide you with some functionality you're looking for. Since TypeScript is an es6 superset, I'm assuming this will work in that context.
I do think it's a little weird, but it's useful to be able to say that "this key exists and its value is null" as opposed to "there is no such key".
That is the difference between not changing a value and changing it to null.
I guess in TS2 there would now also be a difference between a field defined as key: string | null | undefined and a field defined as key?: string | null | undefined, because the first one requires setting the key to one of the values on initialization and the other one not.
I've also found it useful when a function needs to indicate it failed but is in a situation where exceptions are not useful. This is code where the consumer of the function can throw its own much more useful exception or can try to recover from the function failing (eg: it can try and fix the fault). This helps people avoid using exceptions for flow control of the application and lets exceptions be truly exceptional.
Examples:
//3rd party code could dictate 'bar' be in the spot that it is
function needsUndef(foo, bar, other){
if(bar === undefined) bar = expensive_query();
//rest of code
}
needsUndef(42, cachedResultExpensiveQuery, something);
needsUndef(42, undefined, something);
and: foo = getFromDisk(foo_path);
if(foo === undefined)
foo = getFromNetwork(last_resort);
is much nicer than:
try{
foo = getFromDisk(foo_path);
}catch(ex){
//Yes, I know you can filter exceptions, but what if someone forgets or sets too wide
//of a net?
foo = getFromNetwork(last_resort);
}
or:
if(path_isValid(foo_path) && canReadFromPath(foo_path))
foo = getFromDisk(foo_path);
else foo = getFromNetwork(last_resort);When I see null it means a value could not be set or that it was intentionally unset. undefined means it was never set in the first place.