11 ms·
This hits close to home. TypeScript is also my language of choice for 90% of the software I write. I agree with the author that TypeScript is very close to the
by genshii 1y ago
This hits close to home. TypeScript is also my language of choice for 90% of the software I write. I agree with the author that TypeScript is very close to the perfect level of abstraction, and I haven't seen another language with a type system that's nearly as enjoyable to use. Of course, TS (any by extension JS) obviously has its issues/complications. Bun solves a lot of the runtime-related issues/annoyances though.
For the other 10% software that is performance-sensitive or where I need to ship some binary, I haven't found a language that I'm "happy" with. Just like the author talks about, I basically bounce between Go and Rust depending on what it is. Go is too simple almost to a fault (give me type unions please). Rust is too expressive; I find myself debugging my knowledge of Rust rather than the program (also I think metaprogramming/macros are a mistake).
I think there's space in the programming language world for a slightly higher level Go-like language with more expressiveness.
- ashishb 1y agoTypeScript is good as a language. You can't generate static binaries out of it (except Docker images) and that itself is a deal breaker.
- genshii 1y agoYeah, that's definitely a huge drawback. Bun lets you get pretty close though with the `--compile` flag: https://bun.sh/docs/bundler https://bun.sh/docs/bundler Too bad the binaries are 60MB at a minimum :(
- Tade0 1y agoI mean you can, they're just inappropriately large.
- wk_end 1y agoI'd love to see someone develop a compiler for TypeScript that got, say, Ocaml-like performance. There's a bunch of reasons why that'd be tough though - you'd probably want a language very-similar-to-but-not-quite-like-TypeScript.
- ellg 1y agoits called C#
- wk_end 1y agoC# is a lovely language but it's not that similar to TypeScript. The big distinction (for me) is that it's nominally-typed and much more rigid. Unless things have changed a lot since I last touched it (admittedly a while ago): You can't synthesize ad hoc union types (https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types https://www.typescriptlang.org/docs/handbook/2/everyday-type...) There's no notion of literal types (https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types https://www.typescriptlang.org/docs/handbook/2/everyday-type...) There's no type narrowing (which gets you a kind of sum type) (https://www.typescriptlang.org/docs/handbook/2/narrowing.html https://www.typescriptlang.org/docs/handbook/2/narrowing.htm...) Most of the type maniuplation features (keyof, indexed access types, conditional types, template literal types...) are missing (https://www.typescriptlang.org/docs/handbook/2/types-from-types.html https://www.typescriptlang.org/docs/handbook/2/types-from-ty...)
- pragmatic 1y agoClose but not quite.
- williamstein 1y agoThis is probably the closest thing to that: https://www.assemblyscript.org/ https://www.assemblyscript.org/
- wk_end 1y agoThe documentation is really incomplete. It's not at all clear how similar to TypeScript this is...does this support structural subtyping? Type manipulation? Iterators/generators? Async?
- abhijat 1y agoThere used to be reasonml but I'm not sure how active it is these days.
- skybrian 1y agoYou can’t? I haven’t used it, but what’s wrong with “deno compile?” https://docs.deno.com/runtime/reference/cli/compile/ https://docs.deno.com/runtime/reference/cli/compile/
- shim__ 1y agoSounds like electron but for cli
- chainwax 1y agoI does indeed bundle it's runtime into the executable, but this is not dissimilar from Go bundling it's gc into every executable. Granted a compiled hello world Go program will be <2mb while a similar compiled Deno program will be more like 70. I imagine many usecases may not have a storage constraint though, and in that case why not?
- ashishb 1y agoMy problem is running post install step of 100+ npm packages on my machine. Any of those could be malicious. https://www.sentinelone.com/blog/unseen-threats-in-software-development-the-perils-of-trojanized-npm-packages/ https://www.sentinelone.com/blog/unseen-threats-in-software-...
- ashishb 1y agoYou are the fifth person who told me that this can be done but have never used it. If this compile approach is so awesome why don't devs use it?
- daxfohl 1y agoI'm surprised ocaml doesn't have more market share here. Native, fast, robust type system, GC, less special syntax than rust, less obtuse than Haskell.
- pragmatic 1y agoNo libraries. All the niche languages have a chicken and egg problem. Only way around that is to be able to piggy back on C or JavaScript or Java.
- daxfohl 1y agoYeah, though when I say that I mean more like I'm surprised the ecosystem itself hasn't matured more. Rust and Go have both built solid ecosystems up from scratch, but it's a shame that OCaml hasn't since it's a nice middle ground between the two.
- andrewflnr 1y agoI really considered one of the BuckleScript/js_of_ocaml languages for my current frontend project, but went with Typescript for basically conservatism/conventionalism reasons. I was already taking some arguably unnecessary technical risks on that project and wasn't sure I could afford more. I agree that I really wish OCaml or something close to it was mainstream.
- daxfohl 1y agoSounds like a lot of people here are promoting Swift, which IIUC has some roots in OCaml. I have a mac now; maybe I'll finally give it a try.
- lostmsu 1y agoUntil recently it did not have multithreading
- renewiltord 1y agoI recently came to a production Typescript codebase and it took minutes to compile. Strangely, it could not behave correctly without a linter rule `no-floating-promises` but the linter also took minutes to lint the codebase. It was an astounding exercise in patience. Faster linters like oxlint exist but they don't have a notion of cross-file types so `no-floating-promises` is impossible on them. The worst part is that `no-floating-promises` is strange. Without it, Knex (some ORM toolkit in this codebase) can crash (segfault equivalent) the entire runtime on a codebase that compiles. With it, Knex's query builders will fail the lint. It was confusing. The type system was sophisticated enough that I could generate a CamelCaseToSnakeCase<T> type but somehow too weak to ensure object borrow semantics. Programmers on the codebase would frequently forget to use `await` on something causing a later hidden crash until I added the `no-floating-promises` lint, at which point they had to suppress it on all their query builders. One could argue that they should just have been writing SQL queries and I did, but it didn't take. So the entire experience was fairly nightmarish.
- WorldMaker 1y agoPromise<T> is not T and Typescript's type system will catch that in most cases with a simple type assertion (add a type to the function return; add a `satisfies` check somewhere). If it isn't catching it often enough, without a lot more extra type assertions, you may be missing a Typescript strict flag like noImplicitAny. (In general I find that I prefer the full `"strict": true` in the compilerOptions of tsconfig.json and always write for all strict checks.) Also if your codebase is still relying on "explicit" `any`, try `unknown`. Also, yeah Knex doesn't look like the best ORM for a Typescript codebase. Typescript support in Knex is clearly an after thought, and the documentation admits it: > However it is to be noted that TypeScript support is currently best-effort.
- renewiltord 1y agoYeah, the codebase in question was using an “insert into db but do not check result and let exceptions inform” pattern. It was probably transformed from JS at some point which is why it used Knex I must guess. So I suppose I should have found some condition to force use of return values and then unleashed Claude code to fix up linting errors. It’s rarely a GetX resulting in a Promise<T> that’s mismatched and more an insertX followed by an insertY on the same transaction without awaiting the first insertX that’s the problem. Makes it a heisenbug. I wouldn’t mind it if the linter was oxlint speed but eslint was a 5 minute affair on the codebase. It’s sort of a Moravec’s Paradox of its own: web development is much more complex than the HFT strats we deployed (which could compile and sim something faster than this can lint). I suppose I can’t blame the query builder on the tool choice but they were pretty stuck on Knex by then. Your advice is appreciated. Thank you.
- Sophistifunk 1y agoI very much enjoy reading and writing TS code. What I don't enjoy is the npm ecosystem (and accompanying mindset), and what I can't stand is trying to configure the damn thing. I've been doing this since TSC was first released, and just the other day I wasted hours trying to make a simple ts-node command line program work with file-extension-free imports and no weird disagreements between the ts-node runner and the language server used by the editor. And then gave up in disgust. Look, I'm no genius, not by a long shot. But I am both competent and experienced. If I can't make these things work just by messing with it and googling around, it's too damned hard.
- childintime 1y agoFully agree. Try bun.
- WorldMaker 1y agoOr deno.
- mrkeen 1y agoI encountered this trying out PureScript. Looks like a good language, but I gave up after a couple of trips through npm, bower, yarn...