Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

TypeScript is straight up one of the best technologies I work with, rivaled only possibly by giants like Postgres. It takes one of the worst parts of my day - refactoring Javascript code - and makes it straightforward and enjoyable.

TypeScript 2.0 goes beyond that and begins to push the envelope on what type systems can do. Recently I've been loving the combination of discriminated union types and nullable types. It means that you can have code like this:

    function myFunction(x: number | null) {
        if (x === null) { 
            return;
        }

        console.log(x + 1); // x is now a number
    }
The argument to the function is x, which is either number or null (that's what number | null means). But the if statement ensures it's not null by exiting the function, so by the time you get to the log TypeScript has (correctly) set the type of x to be just number!

The types match up exactly with how you'd write the Javascript code. It's awesome and it just works.



> TypeScript 2.0 goes beyond that and begins to push the envelope on what type systems can do

Type systems could do stuff like that many, many years ago. I'm glad that you like these ideas, but let me assure you that TypeScript is far from pushing "what type systems can do".


I realize that I made a factual error in my post and I thank you for pointing that out, but to me your post reads as very condescending, to the point of being rude. It reminds me very clearly why I don't often post comments here.


That seems like a really weird thing to read into k_bx's post. I think you might want to try re-calibrating your "is this post meant personally"-meter :).

FWIW, I didn't see any condescension there. I got more of a "Oh, you ain't seen nothin' yet!" vibe from it. Obviously, YMMV.

EDIT: Words


It sounded a bit condescending to me. Besides that it was an empty comment; a claim with zero citations - not very useful at all.

Anyway, I'm sure that I don't care if an unknown language pioneered something. The language that makes good features popular is the better one.


> a claim with zero citations - not very useful at all.

Gradual typing isn't exactly a TypeScript invention: Typed Racket is gradually typed, has unions and intersections (which in turn date from further back than TR), refinement types, occurrence types, and even comes with a guarantee that typed code won't violate contracts. If the Racket runtime detects a contract violation, blame will always be assigned to untyped code. TR does more than TS does, and it was designed and implemented earlier.

> It sounded a bit condescending to me.

I didn't read k_bx's comment as belittlement of TypeScript: anything that makes JavaScript better is obviously a good thing! (Since we can't get rid of it.) But, as a matter of fact, TypeScript isn't pushing “what types can do”.


I'm not a native English speaker and didn't try to be rude, I'm sorry if you felt like that. I don't encourage you to post comments here more often though, posting more often doesn't necessary means it's good for you and everyone else.


Thanks, I appreciate it.


If you want to find the reason to be upset, you will.


And it adds nothing to the conversation, and has spawned an entire subthread of comments like ours which also adds nothing to the conversations. Its exactly the type of comment that should be banned from HN.


It's not just a factual error, its kind of a sore spot to many people.

TypeScript is a pretty bad type system, but compared to Java and other mainstream ones, it looks like it "pushes the envelop".

Because of this, we're stuck with an half baked, crappy type system designed for mass consumption, and people adopt it with a round of applause.

That's no excuse to me an ass in response to your post...but it's part of why you'll see answers like that.


It's the classic "not invented here" syndrome, but on the level of languages. It's not enough to be able to have strong types in Javascript, they want people to stop writing Javascript, scrap the entire ecosystem, create all new browsers on every platform, and only write in their strongly typed language that's just as flawed as Javascript.


He simply wrote that TS isn't on the edge, without getting personal.

I astouned what some people read into a perfectly reasonable critique...

What about PureScript, it's way beyond TypeScript and still compiles and interacts with JavaScript.


What I find very funny about PureScript is how it has these super-fancy types, designed from the ground up to express things like semigroupoids, lenses and profunctor-based optics... yet it doesn't have a numeric type better than JavaScript's good old floating points.

Just to be clear, this isn't meant as criticism, since I absolutely love how Haskell (and now PureScript too!) exploit algebraic structures to make code more reusable and robust. But the contrast between “can express fancy structures precisely” and “doesn't have precise arithmetic” is very amusing.


Yeah, but in languages that anybody uses?

That people are actually using TypeScript could be the difference here.


I don't have telepathic abilities to guess what exactly author meant. My goal was to let them know that type systems are much more developed than what TypeScript provides, and to encourage them to go out and learn them, read many great books and discover all the type-system goodness that's lying out there for free.


Are you assuming typescript is the _only_ good typed language people use?


C# is one of the most popular languages and is one of the inspirations for TypeScript's type system


> TypeScript 2.0 goes beyond that and begins to push the envelope on what type systems can do. Recently I've been loving the combination of discriminated union types and nullable types.

As a side node, the FlowType system for JavaScript has had these features for over a year now, while TypeScript 2 is still in beta. These are the exact features which made us decide to go for FlowType instead of TypeScript 6 months ago. Happy to see that these two type systems now converge.


still waiting on flow to be cross platform (windows)


Just to add to this, here's the tracking issue, upvote to support it: https://github.com/facebook/flow/issues/6

29 days ago somebody posted an unofficial Windows binary: https://github.com/facebook/flow/issues/6#issuecomment-22989...


I have not used TypeScript, so can anyone explain to me what is the difference between the above the normal JavaScript code like this:

    function myFunction(x) {
        if (x === null) { 
            return;
        }

        console.log(x + 1); // x is now a number
    }
Edit: Or is this example being used to show that TypeScript now support multiple types including null in the parameter?

I assumed that such feature would be available by default.


I haven't used Typescript either, but some of the differences are self evident to me. myFunction(x) can be called with any argument type; tooling can't detect an inappropriate type and output a warning/error(?), so you get to find certain mistakes the hard way; at runtime. "foo"+1 might make sense, but "foo"/1 is garbage, silently propagating 'undefined' up the stack in conventional Javascript, costing time and money for everyone. The user of myFunction(n: number | null) is provided with a meaningful signature during development, this saves time by providing precise information in a concise manner. Those of us that have spent time with statically typed languages and good tooling know what a blessing this is. The Typescript variant offers the possibility of a performance optimization; x+1 might compile down to a single instruction, as opposed to whatever runtime type check has to be invoked when the type of x isn't/can't be known at compile time. I don't know if that optimization is 'real' in practice given our contemporary javascript/typescript stack, but you can bet it will be eventually.


You could call your js function with a string, and rather than a compile time error you'd get broken behaviour at runtime.


Inside the function you also have to continue using x as a number, like you wouldnt be able to accidentally pass it into a function accepting only string as argument etc.


your js version:

y = myFunction(1); // y = 2

y = myFunction("1"); // y = "11"

the ts version wouldn't allow you to compile myFunction("1")


Except for a few cases where Typescript let's you transpile ES6 syntax to JavaScript ES5, the compiler does not change your code; it just checks it for type errors.

The point of the example is that Typescript recently added support for non-null types, but is flexible enough to analyze where types have been further restricted by an early function return.


I haven't had the chance to try typescript yet but I absolutely love postgres, I mean I want to have sex with postgres. It is what is keeping our codebase somewhat sane. It pairs really well with the insufficiently typed javascript/nodejs. With postgres, at least the code interacting with state, the most perilous code, is typed, transactioned and manipulated in the functional sql way. I shudder to imagine in what mess we would be if we had gone with something like mongo.

This thread, with people like you that seem to get it, is definitely making me want to try typescript.


What happens when x is 0?


I think it's just the sample code needs to be x === null. Nothing to do with TypeScript. The sample is a good example to illustrate the union type.


On that note, are there any documentation that explains the == and === operators in Typescript ? The language spec is only briefly acknowledges the existence of those operators.


They behave exactly like they would in JavaScript.


Good question - edited my code to be correct.


does TS2 fix this?

    function uhoh (x:string|number) {
        if (typeof x === 'string') {
            return x.length
        } else {
            return 'bar'
        }
    }

    const a = uhoh('foo') //= string | number
    const b = uhoh(3)     //= string | number


You may already be aware of this, but it's semi-fixable in TS1:

    function uhoh (x:string|number) {
        if (typeof x === 'string') {
            return x.length
        } else {
            return 'bar'
        }
    }
    function uhoh (x:string): number;
    function uhoh (x:number): string;
    
    const a = uhoh('foo') //= number
    const b = uhoh(3)     //= string


I don't know about TS, but in the main competitor, Flowtype, you can give uhoh this type:

    uhoh : ((x : string) => number) & ((x : number) => string)
And get what you expect:

    const a = uhoh('foo') // : number
    const b = uhoh(3)     // : string


Sort of. I tried the above and it reported the following error message:

error TS2354: No best common type exists among return expressions.

So at least it detects the problem. However the type inference algorithm should arguably return a union type here.

I find it good practice to always specify the return type of functions anyway. Then it will pick up cases where you return a type you didn't intend to; instead of just using a more general type it will tell you about the inconsistency.


Typescript does not infer union types for return types. You can explicitly annotate them just fine though.

I suppose the reasoning is that, when adding types to js, this is exactly the kind of bad behaviour you want to catch. But I'm not sure, perhaps there are just technical implications for not inferring union return types.


Exactly. Leaving off the return type annotation is just asking for trouble, and this example proves it.

And the actual type of the const won't be `string | number` -- it will be `any`.

MaulingMonkey[1] has the right idea, though.

[1] https://news.ycombinator.com/item?id=12192240


Kotlin can do something similar, in fact I think the code would work exactly like that if you ported it, but it can also do things like:

> if (a instanceOf SomeClass && a.someGetterOnSomeClassNotAvailableOnTheStaticTypeOfa != null)

Which is pretty awesome because it means you don't have to pollute your code with unnecessary casts.


Kotlin has compile-time null-safety. The ? denotes a type than can be null.

    fun myFunction(x: Number?) {
       if (x == null) return;
       print(x + 1);
    }
if you don't check for null first the compiler warns.

You can also do:

    x?.let {notNullX -> print(notNullX + 1)}
or

    print((x ?: 4) + 1)
https://kotlinlang.org/docs/reference/null-safety.html

It really is an awesome language. Especially the delegated properties are wonderful. I use them to fill javascript-state for redux/react-native.


That does sound awesome. Does it mean that if you have:

  function second(y: number) {
      return y + 3;
  }
And you call second(x) from myFunction, the compiler complains if you haven't put the if() ensuring that null cannot pass to second()?


I am 99% certain that this is indeed the case. Non-nullable types are one of my favorite new additions to TypeScript.

But it goes further than that. TypeScript 2 adds control flow analysis, so adding to the top of a function that accepts a string or an array:

if (typeof someVarThatCanBeStringOrArrayOfStrings === "string") { // turn string into array }

any code below it can safely assume that the variable is string[], as well as the rest of the code that calls this function if this variable is returned.

(correct me if I'm wrong, y'all)


You are almost correct -- it's just that it's not a "safe" assumption.

In your example, the JS interpreter will not throw an error when one provides a number (for example). Your code could break things. But why would this happen?

It's completely unrelated to TypeScript.

A number could be provided by the data, which in all likelihood is JSON from the network (eg: HTTP request or message queue body). Strongly typed languages will give you strongly typed data to protect you from this, but a dynamic language like JS doesn't afford you the same protection.

TypeScript doesn't mitigate this issue -- nor could it. TypeScript ensures your plumbing fits together, not that the sludge flowing through it won't cause a mess.

A strongly typed language will throw an exception before unexpected behavior can occur, JS on the other-hand will attempt to continue. It rarely happens, but since it does you can't say it safely works properly.


That's a good point, but I don't quite see how a strongly typed language fixes this issue. Could you elaborate on that?

If a strongly typed language receives data that is malformed, wouldn't the same problem arise? Isn't it always the case that you only have control over your own plumbing, and put up defenses to deal with external input?

(I have little experience with strongly typed languages, so I'm really interested to understand this a bit better)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: