35 ms·
TypeScript’s quirks: How inconsistencies make the language more complex
- Slashbot 7y agoC#: int x Java: int x Cpp: int x C: int x Some fucking retards at MS derp corp... TypeScrap: x: int
- leetrout 7y agoThe first example doesn't bother me and I think it's a weak argument. TypeScript allows literals[1] as types[0] so it is trying to use the object as a type. The correct use of: printDog({ breed: "Airedale", age: 3 }) is to explicitly cast it: printDog({ breed: "Airedale", age: 3 } as Dog) [0] https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&pln=15&pc=2#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChkHIyYAUARnFAFzIBEFUtAlDQM5hSgDmA3PocXTlKNenABezNh259CRUg1FluU5O04heuAL65cAegPIAculwwAriARhg6EMgAOmsBiEwa7pjmT8CCA6s6AA2EAB0IehcJDDhgiS0gsxMuvpGyACaEKwW1rb2ji6gbpgA4pgAJrFemD7YfvKBIMFhkdGx8aRijEypOkA https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&p... [1] https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types https://www.typescriptlang.org/docs/handbook/advanced-types....
- felixfbecker 7y agoCasting can hide errors. It's better to assign it to a variable first that has a type declaration. const dog: Dog = { breed: "Airedale", age: 3 } printDog(dog) An IIFE is safe too: printDog(((): Dog => ({ breed: "Airedale", age: 3 })())
- BigJono 7y agoYeah and both of those are less readable, and used everywhere add up to a really crap code base relative to the same code in plain JS.
- horseman 7y agoYah, pojs is so much nicer because when you mistype breed as bred you get to debug the issue at runtime for a while changing things that are irrelevant when TS could have told you immediately
- johnghanks 7y agoI would absolutely reject a PR with the IIFE.
- jahewson 7y agoActually this cast is safe in TypeScript, additional variables are unnecessary. The statement ‘const d: Dog’ and the expression ‘d as Dog’ are equivalent w.r.t. type safety. The compiler will error in both cases the if the value is not a Dog.
- agentcooper 7y agoThis is not correct. Following example is valid in strict TypeScript: interface Dog { breed: string; } const dog = {} as Dog; console.log(dog.breed); Using `as` is very unsafe in TypeScript. I've collected more quirks of `as` in this playground: https://www.typescriptlang.org/play/index.html#code/PTAEAMEsGd1AzArgOwMYBdIHtmgLYCGAnqADZZYDW0o0kppRANKAEaLqgrxYBO6KAugCmjUOgAWw3sNAxQyLKADuxcUpkAHXlgAmiVLMjoAUCFAEaBUJsQzxRTbNLCAbqNCoc0dLwOYcADozMABlYVk8PiNkENAJdHRNaAAuEABzYwlEVkCvPGA8SFQdaCx4dGAAFUdhUJLITUqYaERhaGAAdgAWAA4ARgBiFrb8vGFkdABabv6AVgGAZkWABgA2YKQ0ANwYAB4qgD4AClcCUjaU0CqASiuq0ABvE1BQGQFeXDOL4QBuEwAviYTOhaqAAGI4TgAXlAACJSJB0gk4aAAD7w8a6SCIPCojFw1hYUi6OH-EyQSbSeAEQygAAK0jKuGer3gkF4PgAcgRxlcfLxKel-kC4gBJXBuaQkVCWWTKKS4cCWOA0+g0dBKWXoVASCy4LCsVzYRAasHSHS8JhxKCwGw6fSGGi6doc4S6NjCCQEY18YKoUiWGgAYSeL1o6CEslhrNetH6AH1LFdHgCLDRGZycNa4-GEzArvtM8yTqmbtbw69oAAmJOpUAAbQRSJRLDhynQ8DhAF106AAIK8XjEPaQyaHHNxmv5+v7MfoBvdk5NxHI9Bwtsdrvd8vA3PQRZ1q7tzuoywQqGTquHgtyaCjqEnE9dm7hgEikxAA https://www.typescriptlang.org/play/index.html#code/PTAEAMEs...
- lucasmullens 7y agoThe article is just describing quirks, not arguing against them. Specifically for the first example they said "I think that the TypeScript stance here isn’t wrong".
- mekster 7y agoCasting is as bad as using "any". You can make the compiler think anything you throw at it as that type and you can get bitten at runtime.
- alexcole 7y agoThats not 100% true in TypeScript. TypeScript actually only allows "up-casts" and "down-cast" (but if the type is neither a supertype nor a subtype the compiler will throw an error).
- nojvek 7y agoThat’s my understanding too. You just can’t cast types wily Nily.
- seanmcdirmid 7y agoYa, I often have to write “this as any as T” because I’m using T as a self type.
- jahewson 7y agoNope. This is not how casting works in TypeScript. To get an unsafe cast you have to go via the ‘any’ or ‘unknown’ types. e.g. ‘foo as unknown as Dog’
- okbake 7y agoThere are a few casts that are allowed that I would consider unsafe, particularly around unions of literals or using empty object literals: // No error here type Animal = 'dog' | 'cat'; const notAnimal = 'couch' as Animal; // No error here either type Food = { isSpicy: boolean }; const empty = {} as Food; https://www.typescriptlang.org/play/index.html#code/C4TwDgpgBAggdgSwLYEMA2UC8UDkATAewHMcoAfXAYxWFIpwCMIUAnHAbgChOB6HqAGII4ETpQJwAzsCgAPAFyxEqDNnzEOvfgFEWLAiygpJUCLMiVgEPGInSoIRfGTosVAgFdKAC018oAHIEpnoGUAweMh5SKABmouJSMgBebjjiXr5GJs4qXFoAtEXFJaVl5RUF3MJWLLEolNACBAR4UADenFBQwkQs1ggQcMCSitIsvQDaALpcAL7c-kIitklQYAjJySiKza1u7T1wfQNDI4qTOJIoXhA4ADS4kGCQ+og401BzXP66+obGUzmCCWayrew+BBoBC7FptbDtb5aQLBCChQwRKIxeLgmRgYzAFAHObZQRw9hAA https://www.typescriptlang.org/play/index.html#code/C4TwDgpg...
- Kinrany 7y agoCasting may hide errors and is unnecessary in this case: `as const` will work just as well.
- nojvek 7y agoWhy would casting hide errors?
- IggleSniggle 7y agoIn the simple case, if it could be Dog|Cat and you cast as Dog but you get a Cat, and TS could have told you about the error if it hadn't been forced to treat it as Dog. This can be fixed by having your types be derived by runtime validation.
- potatoz2 7y agoThe correct use is to remove the `age` property in this case: if you're not keeping a reference to the object or that property and the called function cannot use it, why have it in the first place?
- alexcole 7y agoThat’s not always true. If you are going to print the object to the console or send it in a network request it’s possible that the additional property is important.
- wvenable 7y agoBut then it should be in the type signature of the object. TypeScript is signalling this as an error because it's a literal passed directly to the function and that property (theoretically) can never be used because it wasn't declared.
- stupidcar 7y agoI don’t agree with the article’s claim that discriminated unions are just a JS compat feature. Many APIs type JSON serialised entities using a string property and this feature makes it very easy to write interfaces and code to work with them.
- _hardwaregeek 7y agoYeah, also this is basically how you'd implement tagged union types if you couldn't have actual algebraic data types like Haskell or ML.
- littlecranky67 7y agoalso bear in mind that support for discriminated unions is what made typescript work nicely with redux actions - that is be able to strongly type actions/reducers/dispatch functions. One thing I love about typescript is they care more for the actual JS/library ecosystem as-is, and don't design a language for an ecosystem that should-be.
- hopia 7y agoPersonally I always found it annoying to manually add a common tag to every interface/type on TS just to have it work like an union type. But since TS doesn't leak types to runtime that's the only way.
- acemarke 7y agoFWIW, I'm a Redux maintainer, and I personally have never understood the point of trying to limit what actions are being dispatched. As long as your reducers and action creators are well typed, it shouldn't matter what other actions might be sent through. On that note, our new Redux Toolkit package is written in TS, and designed to work great in TS apps with a minimal amount of type declarations needed. Really just declare the type of the action in the reducer, and get everything else for free. The new React-Redux hooks API is also a lot easier to use with TS as well. I showed how to use both of those in the Redux Toolkit "Advanced Tutorial" docs page: https://redux-toolkit.js.org/tutorials/advanced-tutorial https://redux-toolkit.js.org/tutorials/advanced-tutorial On a related note, I also recently put up a long blog post detailing my own journey learning and using TS, as both a lib maintainer and an app developer, with my takeaways on the pros and cons of using TS: https://blog.isquaredsoftware.com/2019/11/blogged-answers-learning-and-using-typescript/ https://blog.isquaredsoftware.com/2019/11/blogged-answers-le...
- aratakareigen 7y agoHow does TypeScript ensure encapsulation if it doesn't have nominal types? Edit: The article says "magical hidden properties".
- spion 7y agoYou can hide some of your structure using "private". There are also branded types: https://github.com/spion/branded-types https://github.com/spion/branded-types
- andrew_n 7y agoProgramming TypeScript has a section on “Simulating Nominal Types” [1]. You define a type that’s impossible to create naturally, and provide a function that asserts something is of that type. type CompanyID = string & {readonly brand: unique symbol} type OrderID = string & {readonly brand: unique symbol} type UserID = string & {readonly brand: unique symbol} type ID = CompanyID | OrderID | UserID function CompanyID(id: string) { return id as CompanyID } ... TypeScript can be very confusing sometimes, and given the learning curve I’d caution someone trying to learn modern JS away from starting out with it. But in even small codebases it’s an amazing improvement in safety, especially for refactoring. [1] https://learning.oreilly.com/library/view/programming-typescript/9781492037644/ch06.html#nominal-types https://learning.oreilly.com/library/view/programming-typesc...
- earthly 7y ago> TypeScript can be very confusing sometimes That's not good. A type system should be crystal clear, predictable and reliable. > and given the learning curve Types should not be a complex thing with a steep learning curve. If you know Assembler and C it's pretty clear what types are about. Added complexity to your codebase is what you should try to avoid at all times. We have a limited capacity of things we can think of at a time, developers should therefore focus on things that really matter. In my daily work I see highly complex piles of spaghetti in TS that are 'type safe' and easy to refactor..
- 7y ago
- evmar 7y agoRegarding #2, if the class has any private properties (even if the classes have the same private properties) they are no longer assignable.
- earthly 7y agoI still don't understand what pulls developers to Typescript. The examples given show major flaws in this (duck)type system. That it works when you don't use the 'any' type and when you know how to avoid all the edge cases and workarounds, I know. But when I see an example like this: const shasta = new Cat("Maine Coon") printDog(shasta) > Dog:Maine Coon I see a huge red flag. Coming from C/C++ it looks like a joke. Why are all these front-end static type fanatics not more interested in Dart, Purescript, Elm, etc..?
- jolux 7y agoIt’s structural static typing, a perfectly cromulent class of type system, and much more easily compatible with dynamics types.
- virtue3 7y agoBecause you can get some decent typing with some compiler help AND leverage the entire node/js eco system super easily. Which is kind of the whole point. As someone that's done c/c++/c#/lua/js/ts I've found typescript to be really awesome because it differentiates the types from the objects. Which has given me a much better appreciation of typing rather than the traditional OOP everything.
- sjy 7y agoWhat do you mean by “differentiates the types from the objects”? Could you maybe offer an example comparing TS and C#?
- virtue3 7y agoin typescript I have something like type theThing = { thing1: string, thing2: string }; and the actual object: const thing:Thing = { thing: 'hello', thing2:'more hello' }; "Thing" is not an object, I can't do Thing.new() etc. If I use a class in typescript it behaves just like you would expect C# / Java to. This allows some really fun stuff with unions where I could do something like const operateOnThings = (thing: Thing | Thing1 | Thing2) => { //do something based on what kind of thing it is } Or I can build other types off of it like : type newThing = Pick<Thing, 'thing1'> & { newerThing: number}; Which is something I would have to do a lot of work with interfaces with in order to implement in C#. (I haven't done C# in a few years but I do love the hell out of it).
- smoyer 7y agoSounds like we're about to see a book titled "TypeScript - The Good Parts". That was actually one of my favorite JavaScript books and led to my early adoption of CoffeeScript (since it purposely fixed the "bad" and "ugly" parts at the back of the book.
- habosa 7y agoOk since we have a lot of TS people here maybe someone can help me out. Let's say I have a simple interface with a few fields. I want to make sure incoming JSON conforms to that interface. I realize at runtime the interface isn't there, but is there some tool I can use to compile a utility to check JSON against an interface without having to write a duplicative JSONSchema or something else?
- jvilk 7y agoI wrote a tool that may be useful here; it generates a TypeScript definition file and runtime type checking logic given examples of the objects you want to accept. https://jvilk.com/MakeTypes/ https://jvilk.com/MakeTypes/
- stefan_ 7y agoio-ts [1] is what I think most people use for this 1: https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts
- shhsshs 7y agoPersonally I dislike the fact that io-ts requires taking a pure functional programming approach to this validation. For most cases I just want to throw an error if something doesn't match up. My main use case for this is validating that my UI and backend API have the same ideas about the shape of the data, which will either always work or always fail. All errors should be caught during development and testing, so the "either" case will never realistically be hit in production. Because of this I prefer runtypes [1], because it's much more simple to get my desired behavior. My only gripe is that errors aren't all that descriptive. I guess I could write a function to pipe/fold into the type, throwing a descriptive error if something fails, but I like the simplicity of runtypes. Edit: I just discovered io-ts ErrorReporter [2]. That's way better than my solution, and I'm considering switching now! 1: https://github.com/pelotom/runtypes https://github.com/pelotom/runtypes 2: https://github.com/gcanti/io-ts/blob/master/src/ThrowReporter.ts https://github.com/gcanti/io-ts/blob/master/src/ThrowReporte...
- 7y ago
- nojvek 7y agoTypescript is great but it has its evils because it’s a superset of JavaScript. I really hope we get a modern language like c# where the types are guaranteed compile + runtime and you can’t any-ignore problems. The more I use typescript I realize I want a more sound and stricter language. Like no prototype overriding at runtime.
- hopia 7y agoI agree but it's a big leap to lose Javascript interoperability to gain type soundness. There are many such compile-to-js languages but none nearly as popular as Typescript is.
- seanmcdirmid 7y agoI actually like the unsoundness when I thought I would hate it. It rarely turns out to be a problem for me, and allows some designs I’d never be able to get away with in C#. What I really want from typescript are operators and extension methods (monkey patching is a bad hack), but those would break JavaScript supersetting (typescript isn’t allowed to desugar).
- jbob2000 7y agoNoooo! Go away with those ideas! JavaScript is great because it’s not strict. That’s the flexibility that allows for speed. I have like 30 different APIs I implement at work, but I only pull out a few attributes from each. I don’t want to go to the moon and back creating types for all this crap, I’ll have more than a 100 different types to model because of all the nested data and convoluted structures the APIs return. I want the flexibility to incur tech debt where I want to, I don’t want the language to get in my way. That’s what makes JavaScript great!
- arusahni 7y agoIn strongly typed languages, there are serialization/deserialization libraries that don't require you to type the entire JSON object - just the fields you care about.
- 7y ago
- chmod775 7y agoThe following is purely anecdotally, my opinions is solely based on my personal experience with the language. As someone who learned TypeScript just by using it and without any serious "study", I'll have to disagree the basic premise of the article. I already knew about almost everything the article mentioned and nothing really seemed weird to me at the time. The only point that I did not know about is type narrowing not working on nested objects, because that came up exactly 0 times in about 50k lines of TypeScript so far. Half of the points made are actually TypeScript being lenient (interfaces allowing excess properties, classes working like interfaces). In my book this makes the TS easier to work with, because it gets out of the way when it's not needed. Classes essentially working like interfaces is probably a result of TS wanting to be backward compatible with JS, because when you enrich your existing JS lib with type information, TS can't know about your "classes" - they're a runtime thing. Treating them the same as interfaces can make this much nicer. It also allows 3rd party code to add extra properties to your new-instanciated object and using an interface to reflect the change, but still being able to pass it to stuff expecting the original thing. This way you can have type safety without losing JS features.
- yawaramin 7y ago> TS can't know about your "classes" - they're a runtime thing. Treating them the same as interfaces can make this much nicer. No–this is a very surprising and unsound choice and not at all what you would expect if you previously saw that TypeScript lifts classes into types. > This way you can have type safety without losing JS features. IMHO, you can't get type safety out of an unsound type system. (Which TypeScript is, by choice.) I think surprises like the above drive that point home.
- shhsshs 7y agoTypeScript’s goal isn’t to be sound. Its goal is to be a balance between type-safety and effort. Full type safety would require a lot of runtime checks injected into the final JavaScript, which TypeScript intentionally avoids. JavaScript will never be fully type-safe without fundamental changes, which will probably never happen.
- loxs 7y agoTo me, TypeScript is "perfect". Unlike other strictly typed languages (looking at you OCaml, ReasonML, Haskell), TS has never prevented me from achieving all three of: 1) Be type safe enough to guarantee practically bug-free code (at least with regard to types, you can always have logic bugs) 2) Actually achieve what I want to do in less than a day 3) Upgrade easily when a new version of the language/tooling is released The only thing that's missing is indeed better nominal typing so that we can more easily discriminate between logically separate instances of strings and numbers. For objects it's actually good enough to qualify for "perfect".
- IggleSniggle 7y agoTS has led me to a desire for more functionally pure typed code. I'm super interested in learning OCaml and ReasonML right now so I would be interested in understanding where you felt ReasonML falls flat vs TS.
- loxs 7y agoI definitely recommend trying them, as it will be a great learning experience. It will probably even make your TS better. What you won't be able to do is to actually ship a product easily, as the ecosystem is virtually non-existent. Documentation - virtually non-existent especially for actually creating working products. Of course, there are exceptions to this (like the Facebook Messenger being written in ReasonML), but people tend to underestimate what kind of engineering effort went into that. If you actually want to do stuff by yourself, use TS.
- spion 7y agoAnd that's the funny bit because a lot of the quirks in TS are actually bits that are needed to integrate with other imperfect tools and libraries and deliver a fully functional product.
- austincheney 7y agoThere are problems in their approach: In the first case the behavior is quirky because they are passing an untyped object into a function. If the object is typed the behavior is consistent. The second example is about classes. Classes are created as easy extension objects via inheritance and poly-instantiation. Those ideas are friendly concepts for many developers but they increase complexity so I intentionally avoid classes and use a custom ESLint rule to enforce such. In the third case they can solve for complexity with a simple refactor. The two interfaces are structurally identical so they should be a single interface with either a union on property values (static literals) or by defining a property again a union of other interfaces called by reference.
- namelosw 7y agoIt can only be more complex, then be simple. If Typescript never existed, people got used to simple nominal typed languages like Java would never notice there are much more advance type system ahead, and what can it potentially bring us - the lambda cube, the dependent type, the Curry-Howard correspondence. After everyone have a much better understanding in type and the complexity in Typescript, simpler and more powerful languages would take off.
- twotwotwo 7y agoThese can make sense if you think of TS as better-checked JavaScript, not as a from-scratch design for a statically typed language. Excess property checks catch a common JavaScript bug (typoed property names), structural static typing matches the dynamic duck typing JavaScript authors had already been working with (though I see how nominal would be useful), and it's awesome they found a workable hack for discriminated unions where the code and objects look like what you'd do in vanilla JS, but checked (and requiring the class to have a specific structure seems fine as limitations go). I get how folks coming from "natively" static type systems could find all this weird, but I think by targeting "JS but with better checks" instead of a more fundamental redesign, the TypeScript crew have managed to build something that can get traction where other efforts have not.
- cryptica 7y agoI still don't see the value added by TypeScript. My JavaScript tests catch typoed property names every time. I can't remember the last time I merged code with a typo in a property name. IMO, if you typoed a property name and your tests didn't catch it, it means that either your tests are poorly written or your object didn't need that property to begin with.
- nicoburns 7y agoType systems can be thought of as low-cost (in terms of dev time) declarative tests. Which should leave you with less to test in your actual tests. They also give much quicker feedback than tests.
- cryptica 7y agoIs TypeScript low-cost? Most TS projects I've worked on had at least a 10 to 30 seconds build waiting time per iteration. This means that every time I make a change and run the tests, I need to wait 10 to 30 seconds. With my iterative test-driven approach, I probably iterate about once every minute on average (also, my development iteration time gets faster as I become more experienced in the project). So 30 seconds represents 50% of my total development time. Meaning that I could have written 50% more tests or 50% more features in the same amount of time. And that's not even accounting for my loss of focus incurred as a result of waiting 30 seconds to see the result of my code change. By the time I see the result, the concept in my mind is not as fresh as it was 30 seconds earlier.
- evolveyourmind 7y agoTyspeScript is nothing more than just better type annotations for JavaScript
- esjeon 7y agoLet me be honest, but this article is just horrible. The whole article is for the sake of complaining (though I prefer to call this "nitpicking"). > 1. Interfaces with excess properties ... in immediate objects, which will never be reused. This is nothing worse than golang emitting errors on every single unused variable. There are good reasons to behaviours like this, even though not always preferable. > 2. Classes (nominal typing) It seems like the author straight rejects the idea of structural typing itself, by calling the concept itself a "quirk". This is rather about preference, not right-and-wrong. If this point is to be true, one should also reject duck typing, many other popular dynamic languages, a large portion of software industry, scientific researches, etc. Good luck with that. > 3. Discriminated Unions While I do agree that it's a shortfall of TS type system, the example is simply unrealistic. Using composite values as type discriminator is a bad design. Plus, the compiler is not even allowing anything destructive nor bug-prone.
- the_gipsy 7y agoI don't want to go into detail, but everything the author said is true. These are real quirks, that aren't explained correctly in the documentation. They are all justified, and the author acknowledges this, but nevertheless surprising.
- davedx 7y agoThis article makes me think about the "rust compile times are terrible" blog post from the other day. If you spend a lot of time with a technology, day in and day out, you get intimately familiar with all of its shortcomings, and sometimes you maybe lose some perspective. Having used Rust (enough to see its innovations and promise) and TypeScript (daily), I think they are incredible languages and platforms. Sure, they have shortcomings, but I think it's important to keep in perspective the huge advances in the state of the art they have brought us for these trade offs.
- thosakwe 7y agoNothing wrong with highlighting areas for improvement, though.
- cryptica 7y ago>> Real world JavaScript is inconsistent, messy, and complicated JavaScript is consistent. Expressive languages such as JS are consistent in their permissiveness. It doesn't stop developers from doing irrational things like comparing objects with numbers just like TypeScript doesn't stop developers from writing all other kinds of flawed logic. TypeScript basically only protects code from typos. The worst bugs I see in production systems are almost never caused by typos or by comparing incompatible types; usually they're caused by issues in the flow and manipulation of data; for example the same instance is being modified in two different parts of the code without the other part of the code being aware of it; or in the case of pure FP a function is using outdated instances because a change in the underlying data source did not propagate through correctly, etc... TypeScript is to a software developer what a spell checker is to a book author; it's convenient but once you run the final product past your editor-in-chief (whose analogy in the software world are unit/integration tests), the spell checking didn't actually add any value; at best it saved your editor-in-chief some time. It has no bearing at all on whether or not you'll get a Pulitzer Prize or a top ranking on Amazon. The downside to TypeScript is compile time and this is a significant drawback IMO because it slows down iteration time significantly. Time spent waiting for the build to finish is time that was not used to add new tests and new features. If you add up all the time that all developers on a project spent on waiting for the build (or lost their focus/train of thought as a result of waiting for the build to complete), how many extra unit or integration tests could have been written using that lost time? I think if you do the math, you will find that TypeScript is a net liability to the project.
- lazarljubenovic 7y agoYou obviously never wrote TypeScript with strict flag turned on. It does control flow analysis, not just typo checking.
- cryptica 7y agoIt does 'Control Flow Based Type Analysis' - Meaning that it only analyzes control flow for the sole purpose of determining type correctness which adds almost no value to the project. It doesn't prevent asynchronous control flow issues like for example; - Having two different parts of the code simultaneously (asynchronously) mutating the same object and causing data inconsistencies. - Your code starts a new asynchronous job (e.g. setInterval) in the background without killing the previous/existing job which was launched earlier. - An event listener was registered for the same event multiple times (e.g. from inside another event handler) without unregistering the previous listener and so every event now triggers multiple updates instead of one (and CPU usage keeps going up and you have a memory leak). - It doesn't tell you when you forgot to trigger a specific event - Or guarantee that two different parts of your code never run in parallel (asynchronously) when mutating some state. - Or that you missed an edge case and forgot to update a specific instance's property - Or that you were modifying the original instance of the object instead of merely a copy/clone of it as you assumed (or the opposite was necessary and you made the reverse assumption) Only a human brain can prevent those issues (and the list of such difficult issues is practically infinite; my list is a tiny sample) and those are the real issues in software development, not typos and auto-completion. Unless you're a web developer and your job only involves writing static webpages, you are likely to encounter much more difficult problems in your career besides not having automatic method name completion or typo prevention mechanisms. These problems I described above are complex enough that they make all the problems solved by TypeScript seem negligible. TypeScript's compile time delay becomes a bottleneck when trying to debug and resolve real difficult problems.
- alkonaut 7y agoBeing able to gradually introduce types into an existing code base seems like a poor reason to use unsound or quirky features in a language. I’d then much rather use a small and consistent language if I’m going to compile to js anyway, even if it’s not useful as a migration path. What seems like a good reason for accepting language design tradeoffs on the other hand is the package ecosystem. A language that doesn’t work seamlessly with existing third party js is probably doomed. It’s not too difficult to write a tiny language that is nice and consistent and compiles to js, but few will use it if you need ffi to interact with js code. The impressive engineering effort in TS is all about these tradeoffs. This is why I’m having a hard time loving TypeScript, it’s a language for solving a real world problem (bringing types to the js ecosystem) in a pragmatic way, and that rubs me the wrong way. It acknowledges that js, js developers, and js packages are not going to going away any time soon.
- DonHopkins 7y agoFrom the HN discussion about the video of "A Conversation with Language Creators: Guido, James, Anders and Larry" https://news.ycombinator.com/item?id=19568378 https://news.ycombinator.com/item?id=19568378 https://www.youtube.com/watch?v=csL8DLXGNlU https://www.youtube.com/watch?v=csL8DLXGNlU I posted these Anders Hejlsberg quotes, who co-designed TypeScript, C#, Delphi, Turbo Pascal, etc: https://news.ycombinator.com/item?id=19568378 https://news.ycombinator.com/item?id=19568378 >"My favorite is always the billion dollar mistake of having null in the language. And since JavaScript has both null and undefined, it's the two billion dollar mistake." -Anders Hejlsberg >"It is by far the most problematic part of language design. And it's a single value that -- ha ha ha ha -- that if only that wasn't there, imagine all the problems we wouldn't have, right? If type systems were designed that way. And some type systems are, and some type systems are getting there, but boy, trying to retrofit that on top of a type system that has null in the first place is quite an undertaking." -Anders Hejlsberg >Andrew Hejlsberg: >Maybe I'll just add, with language design, you know one of the things that's interesting, you look at all of us old geezers sitting up here, and we're proof positive that languages move slowly. >A lot of people make the mistake of thinking that languages move at the same speed as hardware or all of the other technologies that we live with. >But languages are much more like math and much more like the human brain, and they all have evolved slowly. And we're still programming in languages that were invented 50 years ago. All the the principles of functional programming were though of more than 50 years ago. >I do think one of the things that is luckily happening is that, like as Larry says, everyone's borrowing from everyone, languages are becoming more multi-paradigm. >I think it's wrong to talk about "Oh, I only like object oriented programming languages, or I only like imperative programming, or functional programming". >It's important to look at where is the research, and where is the new thinking, and where are new paradigms that are interesting, and then try to incorporate them, but do so tastefully in a sense, and work them into whatever is there already. >And I think we're all learning a lot from functional programming languages these days. I certainly feel like I am. Because a lot of interesting research has happened there. But functional programming is imperfect. And no one writes pure functional programs. I mean, because they don't exist. >It's all about how can you tastefully sneak in mutation in ways that you can better reason about. As opposed to mutation and free threading for everyone. And that's like just a recipe for disaster. And these Larry Wall and James Gosling and Guido van Rossum quotes: >James Gosling wants to punch the "Real Men Use VI" people. "I think IDEs make language developers lazy." -Larry Wall >"IDEs let me get a lot more done a lot faster. I mean I'm not -- I -- I -- I -- I -- I'm really not into proving my manhood. I'm into getting things done." -James Gosling >"In the Java universe, pretty much everybody is really disciplined. It's kind of like mountain climbing. You don't dare get sloppy with your gear when you're mountain climbing, because it has a clear price." -James Gosling >"I have a feature that I am sort of jealous of because it's appearing in more and more other languages: pattern matching. And I cannot come up with the right keyword, because all the interesting keywords are already very popular method names for other forms of pattern matching." -Guido van Rossum Also: https://news.ycombinator.com/item?id=19568860 https://news.ycombinator.com/item?id=19568860 DonHopkins 10 months ago [-] >Anders Hejlsberg also made the point that types are documentation. Programming language design is user interface design because programmers are programming language users. >"East Coast" MacLisp tended to solve problems at a linguistic level that you could hack with text editors like Emacs, while "West Cost" Interlisp-D tended to solve the same problems with tooling like WYSIWYG DWIM IDEs. >But if you start with a well designed linguistically sound language (Perl, PHP and C++ need not apply), then your IDE doesn't need to waste so much of its energy and complexity and coherence on papering over problems and making up for the deficiencies of the programming language design. (Like debugging mish-mashes of C++ templates and macros in header files!)
- kjtekn 7y agoI like how nobody has realized that typescript is classic Microsoft embrace, extend, extinguish. Oh no, they have "turned a corner". This is a different Microsoft! Haha.. they are exactly the same. Every single company has wanted to try and control JavaScript as it takes over more and more of the roles other languages used to fill. Google failed with their new language, Microsoft is having some success. Google claimed "javascript was too slow, so we need Dart". Hmm, turns out to be complete bullshit and electron applications are now the standard way to create desktop applications. Microsoft is claiming "you need static typing", which is more bullshit. First Microsoft embraced JavaScript, then they made TypeScript to extend it, and now there is talk of "hey why not just use c# with web assembly etc". "why not just make deno TypeScript only". "what if Chrome only ran TypeScript, would it be faster?". With vscode->typescript->github, Microsoft is managing to gain control of the masses of mediocre developers, while the good programmers will always be elusive. A digital divide is getting bigger.
- lexicality 7y agoThe only electron app I've ever used that wasn't slow/terrible is VSCode which happens to be written in typescript by Microsoft and it still occasionally decides to use 100% of my macbook's CPU making it entirely unusable until I restart, so I'm not sure that's a very good argument.
- ravenstine 7y agoDo you think that's actually thanks to TypeScript? From what I know, TypeScript doesn't have an inherent performance quality that makes it better than JavaScript.
- lexicality 7y agoNo, typescript has no impact on runtime performance that I know of.
- iLemming 7y agoAfter using Clojurescript for some time, I don't even understand anymore what kind of problems Typescript supposed to be solving. Sometimes it feels it causes more headaches, to be honest.
- mpawelski 7y agoWell, typescript is constantly improving over the years, witch each release you are able to represent more real-world JS patterns and type system is getting more strict options. So this 3 points from article might be improved in future. About the point the article makes: 1) I remember when excess property check was introduces I was really happy! Because I remembered bug that would be caught with it. I had some interface with optional properties in common library and I renamed property name. Of course when I updated this library in another project I didn't get any compile errors because this was optional property and now I was just passing some extra property which was ignored. Excess property check would have found it because I was passing object literal. Structural typing is great choice in Typescript because it's basically type-safe duck-typing which is used everywhere in Javascript projects. It's not uncommon to have one component that accept objects with some properties but this object contains many extra properties because it came from different component and these properties are used elsewhere. It's standard pattern in Javascript world. But when your function requires some object of given shape and you are creating this object right now using literal syntax, then it's really likely that you made a mistake. Why create extra properties for just created object when you clearly see they are additional? And I read that Typescript teams is very happy with this feature[0]. However, excess properties check is great but useful only on call side. I cannot say that my function doesn't accept extra parameters. I would really love to get Exact types[1]. Which would allow me to force not having extra parameter in passed object. 2) As mentioned in article, Flow decided to have classes nominally typed. In Typescript everything is structurally typed so it's actually more consistent ;) I really hope we'll get nominal typing and opaque types sometime in future. I read TS team was thinking a lot how to do this. I don't remember what is the current status of this. 3) For me it's more problematic that Typescript doesn't narrow types of an union when you do conditional check. The reason is that in general it is unsound (but I think it would not be if you had only union of Exact types, that's another reason why I would love to have Exact types!). Example in article doesn't have this problem so I guess this could have been improved. Sound like minor issue for me but maybe author could create suggestion on github to improve it and allow discriminator to be nested? [0] https://github.com/Microsoft/TypeScript/issues/12936#issuecomment-284590083 https://github.com/Microsoft/TypeScript/issues/12936#issueco... [1] https://github.com/Microsoft/TypeScript/issues/12936 https://github.com/Microsoft/TypeScript/issues/12936
- drderidder 7y agoAfter using TypeScript for the past couple of years, I've come to see it as simply another "embrace and extend" maneuver by Microsoft carve off a chunk of JavaScript mindshare, preying upon the naïveté of less-experienced developers who've fallen for the "static typing is safer" myth. TypeScript's decision to disallow JSDoc within .ts files [1] for example doesn't contribute anything positive to my impression of this syntactic pocket-protector. While the type hinting it provides is useful, the tradeoffs of added complexity, tool dependencies, and cross-compiling phase have made it more trouble than its worth in my opinion, particularly since tooling to provide code introspection and type hinting has already existed for a long time [2]. For new projects, I've begun using straight JSDoc, which is working beautifully with minimal setup [3] and provides all of the benefits I ever found useful about TypeScript, while remaining completely unobtrusive otherwise[4]. 1. https://github.com/microsoft/TypeScript/issues/20774 https://github.com/microsoft/TypeScript/issues/20774 2. https://ternjs.net/ https://ternjs.net/ 3. https://medium.com/@trukrs/type-safe-javascript-with-jsdoc-7a2a63209b76 https://medium.com/@trukrs/type-safe-javascript-with-jsdoc-7... 4. https://fettblog.eu/typescript-jsdoc-superpowers/ https://fettblog.eu/typescript-jsdoc-superpowers/