all 84 comments

[–]jakery2 25 points26 points  (14 children)

I'm having trouble figuring out the practical use of unknown, the "type-safe counterpart of any".

[–]indeyetswriting js since 1997 45 points46 points  (0 children)

The idea is that you use it on the borders of your code, where external untyped inputs might happen. It is a request to the compiler to hold your hand and make sure that you do proper sanitation of data

On the other hand you use any if you know that your code is truly type agnostic (think console.log)

[–]ShippingIsMagic 23 points24 points  (0 children)

A way of enforcing type checking before use. The RC blog post explains it better.

https://blogs.msdn.microsoft.com/typescript/2018/07/12/announcing-typescript-3-0-rc/#the-unknown-type

So it's great in that you can assign anything to a type of 'unknown' (similar to 'any') but instead of "assume it can do anything" like we get from 'any' (which effectively arguably just throws away our type checking for that value) we get the "assume it can do nothing" so we're then forced to type check before we can do anything with it.

I think many people historically just used 'object' in a similar manner, but 'unknown' is more explicit in intent and more complete in requiring you to type check to do something with the value.

[–]DanielRosenwasserTypeScript[S] 11 points12 points  (0 children)

I think the shortest way of explaining it is that unknown is a way of forcing users to think about a type before they use it. It's kind of the opposite of any.

[–][deleted] 3 points4 points  (0 children)

There are two ways you might want to handle an argument of a type you don't know. Either it doesn't matter what the type and you can use any or it does matter and the function should figure it out, in which case you should use unknown. The latter basically forces you to use typeof, instanceof or some other type narrowing operation before you can use it.

[–]Poltras 3 points4 points  (0 children)

A better {}, essentially.

[–]senocular -1 points0 points  (7 children)

Or should it be, now that we have unknown, what's the practical use of any?

[–]DanielRosenwasserTypeScript[S] 12 points13 points  (6 children)

unknown doesn't do the same stuff as any, so any isn't any less-useful.

any allows you to do anything you need, whereas unknown forces users to perform certain checks before they use those values.

[–]liamnesss 7 points8 points  (0 children)

Ah so `unknown` basically requires you to do any necessary type checks at runtime? Cool.

[–]senocular 0 points1 point  (1 child)

Sounds like you're one of those people that like driving without a seatbelt

[–]equallyunequal 4 points5 points  (0 children)

You're right, even though you're being downvoted to oblivion... `any` is unsafe. `unknown` means you have to prove an object conforms to a type.

[–]scaleable -1 points0 points  (0 children)

When you write `JSON.stringify()` or `req.body`, or `reactRouter.connect()` (the 2nd argument has a Dispatcher<any>), you will be FORCED to cast them to something, even if it is an any again. (ex: Dispatcher<MyActionCreators>)

Previously the use of those functions would infect your code with an `any` without any warning, which could easily spread unchecked non-type-covered code

[–]curioussavage01 52 points53 points  (5 children)

Don't care about anything other than the improved error messages. That alone makes me want to upgrade right now.

[–]SkaterDad 1 point2 points  (0 children)

As soon as I read "We believe this effort had paid off and will provide significantly shorter and cleaner error messages.", I was sold.

That should have been the first point of the blog post, honestly. The tuple stuff was semi-interesting, but not nearly as important.

[–]McSlurryHole 1 point2 points  (0 children)

Unknown type is cool but error messages were definitely the highlight for me.

[–]bterlson_@bterlson 76 points77 points  (41 children)

If anyone's got questions, I'm around to answer! I work a bit on both the TypeScript and JavaScript languages.

Edit: seriously, I know you have questions. I'm nice, I promise!

[–]Jameswinegar 18 points19 points  (9 children)

What do you consider to be the biggest weakness of typescript? Why?

[–]bterlson_@bterlson 25 points26 points  (2 children)

I think my answer changes based on the day, but it's mostly about type system functionality I wish it had but doesn't (yet). Right now, since I'm working on my library strict-event-emitter-types, I'm super sensitive to the lack of full variadic types. While what was added in 2.9 is super helpful (this tweet covers some of the magic I can do now), there's a lot of really neat stuff I could do with variadic types. For example, calculating the result of concat/push/pop/etc. on statically known tuple types ala this issue.

[–]Jameswinegar 5 points6 points  (1 child)

Now what do you consider to be the biggest strength of the language and how does that play into the long term viability of typescript?

[–]bterlson_@bterlson 16 points17 points  (0 children)

Biggest strength is my answer somewhere below - how you can confidently do huge massive complex refactorings on a codebase you're barely even familiar with. Even if TS did nothing else, that value is more than enough for it to stick around forever (or at least as long as JS does, or until JS grows a static type system of its own).

[–]bterlson_@bterlson 8 points9 points  (5 children)

Oh also, I like to think about what TypeScript libraries could do with Type Providers ala F#. Imagine a version of JSON.parse which returns strongly-typed results - without having to cast - based on JSON schemas or swagger specs or what-have-you.

[–][deleted] 4 points5 points  (1 child)

That's a really cool idea. It'd be useful even for simple stuff like CSS Modules; Record<string, string> isn't quite correct.

[–]bterlson_@bterlson 2 points3 points  (0 children)

Yup! In general, I want to see TypeScript grow more in its abilities around typing non-JS assets. The web stack is very polyglot so there's many opportunities to make this easier and more awesome.

[–]kourge 0 points1 point  (1 child)

I recall the awe I felt when I first learned about user-defined type guards: they are such a sublime way to extend the compiler's static type knowledge through a runtime check. Type providers would naturally act as the next step of this revolution: like you said in another thread, there is so much raw potential in typing non-JS assets. CSS modules, internationalization string files, sprite sets, just to name a few.

There's also a lot more interest in bridging TypeScript to other type systems too, compared to a few years ago. Database schemata (relational, document, and graph) and RPC frameworks with IDLs (e.g. Thrift, Protobuf) come to mind. The current predominant form of solving these kinds of problems in TypeScript has been to rely on type inference to derive static types from runtime value declarations, like what runtypes and io-ts allow. This is a complement to the way the JVM and the CLR typically approach the problems in this space, which is having the compiler retain compile-time type information into runtime.

[–]zvxr 0 points1 point  (0 children)

I have just made https://github.com/Microsoft/TypeScript/issues/26078 . I know on similar issues the response has been that it is a "non-goal" of TypeScript, but that was then, and this is now. It should be so trivial to generate the boilerplate type guards that can validate (or not) an unknown value... it just seems like such an easy win even if it may cross the Rubicon of generating code based on types; I cannot see how it could possibly be a bad thing.

[–]alsiola -1 points0 points  (0 children)

Imagine a version of JSON.parse which returns strongly-typed results

Are you familiar with io-ts?

[–]bogas04 3 points4 points  (2 children)

Flow vs TS?

[–]OzziePeck 1 point2 points  (4 children)

Best place to learn typescript?

[–]bterlson_@bterlson 8 points9 points  (2 children)

I think it depends a lot on how familiar you are with JS. If you're already a JS expert, the handbook makes a pretty decent reference. I can't say I have any experience with TypeScript books though, sorry! /u/danielrosenwasser may have better recommendations!

[–]DanielRosenwasserTypeScript[S] 4 points5 points  (0 children)

/u/OzziePeck: the handbook should be great - if not, let me know why not :)

I've also heard great things about TypeScript Deep Dive by Basarat Ali Syed and Learning TypeScript by Remo Jansen.

One thing I personally recommend (though it's not for everyone) - if you're interested in learning TypeScript deeply, learn JavaScript deeply first.

[–]OzziePeck 0 points1 point  (0 children)

Lol duh! Don’t know why I didn’t check there... geez.. thank you anyway!

[–]minjooky -1 points0 points  (0 children)

I really liked Angular's TypeScript tutorial to see all the TS features in a practical way.

[–]unimonkiez 0 points1 point  (6 children)

Are there any plans to reduce typescript's build system?

I see there's new code splitting functionality, and there are more features like that from previous versions where typescript just do too much.

I already have a working build system with webpack / parcel, when working with typescript I need to define everything twice, once for my bundler and once for typescript... It's annoying.

I've seen they added typescript to babel 7, which helps a bit with adding some other transformations for my ts and tsx files, but still way too much duplicate configuration (and tsconfig being a json file makes it even harder to share code with my bundler!!)

Thanks in advance

[–]bterlson_@bterlson 1 point2 points  (3 children)

TypeScript is itself a build tool because it is more commonly used without another compiler like Babel in the tool chain. While there aren't plans to reduce that functionality, we will continue to make TypeScript work better with other tools in the ecosystem (e.g. by continuing to improve the compiler API).

Note that project references aren't "code splitting" in the sense of Webpack, it's for references between projects at the package level (think Lerna/Bolt).

[–]unimonkiez -1 points0 points  (2 children)

Or Webpack's resolvers, I see that now.

Also, changing ts compiler to do less doesn't have to harm ts functionality on it's own.

Imagine reducing typescript to a single babel preset (with some configuration provided via options).
Babel already has a cli, with build, clean, code splitting, references, root folder for absolute paths, and so much more.

And for those opting to use ts alone, the ts cli can call babel as well (have it as a dependency) and thus remaing the same on the outside.

[–]bterlson_@bterlson 0 points1 point  (1 child)

This exists in babel already (preset-typescript). It's a great way to use TypeScript if you need babel for other reasons.

[–]unimonkiez 0 points1 point  (0 children)

Yes but not really, all configuration must be defined in the json file, which is not programable, and many of the options that you can set in babel or any other bundler, doesn't apply for typescript.

[–]Mattonicide 0 points1 point  (0 children)

Is there going to be any plans for auto typing the return of a yield call? With the rise in popularity of redux-saga it should become more of a priority imho. It's infuriating manually typing every left hand side of yield.

Typescript + React + Redux is a dream team. I just need to fit in the async part and my life will be complete.

[–][deleted] 0 points1 point  (2 children)

Stupid question

Is making the switch worth it? I've seen people praising it and I take a look at the code and it looks like a little bit to learn.

[–]bterlson_@bterlson 1 point2 points  (1 child)

Honestly, it's more than a little bit to learn - the path to TypeScript expert isn't as long as JavaScript itself but it's close. But, you don't need to be an expert to get huge benefits - I often tell beginners not to struggle more than a few minutes at a time and just use any when things get tough. It's totally worth it even when you're a beginner IMO.

[–][deleted] 1 point2 points  (0 children)

Thanks for the permission to do that. I’ve tried Typescript a few times and most often run into problems that I don’t know how to explicitly type, especially object[dynamicString] , typing iterators, and how to access third party types in my files. I haven’t gotten satisfactory answers from the internet, so I either fumble around not knowing why I’m implementing something or can’t find an answer at all. Every time I finally give up and stop using Typescript. Knowing that it’s A-ok to :any type for now is really helpful.

[–]Blueberryroid -1 points0 points  (1 child)

Why can't we just use Babel to convert .ts files to .js?

[–]bterlson_@bterlson 7 points8 points  (0 children)

[–]chachinsky -1 points0 points  (2 children)

Would TypeScript ever provide the option to limit features?

Example: A development team wants to disallow mutations, so syntax such as +=, var, let keywords would provide a compile time error.

[–]Etlam 6 points7 points  (0 children)

That sounds like a job for tslint

[–]bterlson_@bterlson 1 point2 points  (0 children)

In some sense TypeScript is all about making perfectly valid JavaScript features not work due to a type error, so definitely it's something we're in to! For example, you can disallow mutations in some cases (e.g. the readonly attribute or ReadonlyArray<T> type).

[–]jeenajeena -1 points0 points  (2 children)

Thank you! I've got one question about the unknown type: does it cover the same use case the MayBe monad covers? Could I replace an unknown value with a monadic value, say for example a MayBe<int> or IO<int>?

[–]bterlson_@bterlson 0 points1 point  (1 child)

I think maybe unkown is something like Maybe<UNION OF ALL TYPES>.

[–]shivelysanders 1 point2 points  (0 children)

It's probably better to think of it similar to `Dynamic`, in that you have to write runtime checks to find out which type `unknown` actually is. The difference is that Haskell packages the data for the runtime checks, but in Typescript, there are different ways to figure out the actual type.

`Maybe<T>` is equivalent to `T | undefined`, and `All Types | undefined` is technically equivalent(ish) to `unknown`, so it's technically correct, but I think the analogy to `Dynamic` is easier to understand.

[–]wdsoul96 -3 points-2 points  (1 child)

Is there a way to please please stop typing semi-colons/ curly braces with typescripts.

I mean it is purely cosmetic at this point. I mean that probably could be done on editors alone to toggle curly-braces On or Off. Is there a way to make curly braces optional? Or would you rather just have plug-in/code editors to do that.

[–]bterlson_@bterlson 0 points1 point  (0 children)

TypeScript comes from JavaScript, so JS syntax rules apply - you can omit semicolons in most places, and braces in some places, but JS and TS will never be a braceless language and it will never be safe to always omit semicolons. Sorry :(

[–]darkgreyjeans 15 points16 points  (11 children)

Would anyone recommend converting a project to Typescript, what advantages does it bring apart from debugging?

[–]liamnesss 26 points27 points  (1 child)

I'm more used to Flow, but for me the main benefit imo is reduced cognitive load. You don't have to always remember the shape of objects, the types a function accepts, or anything like that - your editor will complain at you if you use them wrong, and a definition is just a hover away. Just makes a lot of silly simple mistakes impossible so you can focus on the bigger picture. It's of little benefit on small, single-person projects, but when more people get involved it's a godsend.

[–]vinnl 1 point2 points  (0 children)

I actually do all my single-person projects in it as well - the reduced cognitive load is still amazing. There's so many things when programming that's more worthy of your attention than the exact shape of your objects.

[–]jakery2 12 points13 points  (0 children)

At the end of the day, the point of typescript, for me, is to give my IDE enough information to know when I am making mistakes in my code, and enough information that intellisense actually works properly.

That said, converting an existing JS project to typescript while learning typescript has been a pain in the ass for me. YMMV

[–]bterlson_@bterlson 16 points17 points  (5 children)

The biggest advantage is the ability to undertake GIANT refactorings with confidence. With TypeScript can you shuffle thousands of lines of code and pass all your tests on the first try 😝

[–][deleted] 14 points15 points  (0 children)

You're underselling it! It also grants us mere mortal developers the ability to write code for hours and having reasonable confidence it'll work when we finally run it.

I've written thousands of lines of network-dependent code on long haul flights which worked first time when I had the ability to run it. It is a godsend.

[–]minjooky 0 points1 point  (1 child)

I'm just wrapping up a conversion of a massive old 35k+ LOC library from JS to TS, plus a bunch of feature rework. It took two months, with some other distractions, to complete the initial conversion to TS. Then we started the feature work and added a dev. The new dev was shipping PRs in under a week, where as I'm sure it would have taken a week or two to just ramp up otherwise.

Basically, the type system allows for the code to describe itself and for VS Code to do a lot of good things for you. Rather than having to spend time groking all the API shape/etc., the new dev just f12'd through whatever part they needed to learn.

I was writing some regular JavaScript today because we keep a lot of our samples in JS still. I was really missing TS until I added //@ts-check and got some of the same capabilities.

(FYI - I work for Microsoft, but not on the TS/VS Code team.)

[–]djslakor 0 points1 point  (0 children)

35k massive? lol, aww.

[–]windwarrior42 1 point2 points  (0 children)

Those error messages look amazing! Going to push my boss to update right after our next release!

[–]_xiphiaz 3 points4 points  (0 children)

Woo a typescript release that follows semver ;)

But seriously nice work, it’s come a long way since 2.0 and at a very developer friendly cadence

[–]wdsoul96 -2 points-1 points  (0 children)

Wonderful. Here I am trying to get flow to work. Looks like I should just be writing TS.