It infers types. If I do
const data = [
{ name: 'bob', age: 35, state: 'CA' },
{ name: 'jill', age: 37, state: 'MA' },
{ name: 'sam', age: 23, state: 'NY' },
];
Typescript knows data is an array of { name: string, age: number, state: string }. I don't have to tell it.Further, if I use any field, example
const avg = data.reduce((acc, { age }) => acc + age, 0) / data.length;
It knows that `age` is a number. If I go change data and add an age that is not a number it will complain immediately. I didn't have to first define a type for data, it inferred it in a helpful way.Further, if I add `as const` at the end of data, then it will know 'state' can only be one of `CA`, `MA`, `NY` and complain if I try to check it against any other value. Maybe in this case 'state' was a bad choice of example but there are plenty of cases where this has been super useful both for type safety and for code completion.
There's insane levels of depth you can build with this.
Another simple example
const kColors = {
red: '#FF0000',
green: '#00FF00',
blue: '#0000FF',
} as const;
function keysOf<T extends string>(obj: { [k in T]?: unknown }): readonly T[] {
return Object.keys(obj) as unknown[] as T[];
}
type Color = keyof typeof kColors;
const kAllColors = keysOf(kColors);
Above, Color is effectively an enum of only 'red', 'green', 'blue'. I can use it in any function and it will complain if I don't pass something provably 'red', 'green', or 'blue'. kAllColors is something I can iterate over all colors. And I can safely index `kColors` only by a ColorIn most other languages I've used I'd have to first declare a separate enum for the type, then associate each of the "keys" with a value. Then separately make an array of enum values by hand for iteration, easy to get out of sync with the enum declaration.
C#'s anonymous type shares some flexibility of structural type system even though it still a nominal type.
> A language would only need a single "newtype" or "nominal" keyword to create nominal types from structural types.
I think you also can add `structural` keyword & apply structural type system in generally nominal type system as well if we're talking about adding feature.If you have to define the Enums in one place and then repeat them all in another just to associate data with each one you’ve failed
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF)
}Also, I think there was some performance issue with too much inference? Could be wrong, could also be fixed.
1. can be read without a compiler, useful when reading PRs
2. They make the compiler work less, it's easier to check than infer
var arr = [ 1, 2, 3];
You have to write something like var arr = new int[] { 1, 2, 3 };
However if you have previously declared `arr` to be of type `int[]` (or another collection type such as `List<int>`), then you can write arr = [ 1, 2, 3 ];
I haven't used TypeScript so don't know if it distinguishes between arrays and lists, and if so how it determines one or the other in inferred types. Would be curious to know.Java has it through a compiler extension (https://github.com/manifold-systems/manifold/tree/master/man...) but I don't know many other languages that support this feature.
As much as I dislike the entire Javascript runtime environment, I find TypeScript to be the best typing system out there for any imperative language.
The other widely-used one is Go with its structurally-typed interfaces.
The truth is that C# is probably the best designed mainstream language out there.
C# was known as a language with lowest amount of WTF per LoC
The sequence of turbo pascal / delphi / c# / typescript which brought us LSP as a sidekick (!) IMHO has benefitted the whole industry at least as much as "transpile c# to ecma script via typescript" . no. much much much more.
I do not see a problem with MS also having an internal use case .
you know I wouldn't stop using python "because" Guido now works at MS ...
By contrast, .NET is controlled by Microsoft (with veto over board decisions [2] and code changes [3]), integrates Microsoft's telemetry to send your data to Microsoft by default [4] and deliberately hobbles features to benefit Microsoft [5].
[1] https://peps.python.org/pep-0013/
[2] https://dotnetfoundation.org/about/policies/.net-foundation-...
[3] https://github.com/dotnet/runtime/blob/main/CONTRIBUTING.md
As far as the other direction, JS has a somewhat similar (but rather more complex) situation to Python with its steering committee being Ecma International's TC39 (Technical Committee 39).
Ecma International has similar By-Laws and Rules designed to manage conflict of interest and too much power consolidate in a single employer of committee members. Ecma is maybe even a little "stricter" than Python because its rules consider the companies themselves to be the members, and companies only get one vote no matter how many employees interact with the process.
Furthermore, couldn't the convergence of TypeScript towards C# be simply a result of shared goals and values of the two languages, especially considering they have the same principal designer?
C# language team is also really good. They did not do a lot of mistakes in the 25+ years. They are a very valid source of OO and OO-hybrid concepts. It is not only TS/JS but also Java and C++ who often look to C#.
The story was not to transform C# code to JS but to use C# to write the code in the first place and transpile it. Not for the sake of having .NET usage but for the sake of having a good IDE.
If my memory serves, .NET and WinFS were the two major forces that sunk Longhorn, and both have been given their walking papers after the reset [1].
.NET and C# have grown to be mature and well-engineered projects, but the road there was certainly not without bumps. It's just that a lot of the bad parts haven't spilled outside of Microsoft, thankfully.
Longhorn was going to be more than that. Microsoft did have Singularity/Midori projects, started around the middle of Longhorn/Vista, and continued much longer after Vista released to build out the managed microkernel concept. It's been about a decade since they've put any work into it, though.
Joe Duffy mentions on a talk, that even with Midori running production workloads, Windows team could not be changed their mind.
Meadow uses a C++ based microkernel, the whole userspace is based on .NET, by the way.
Source: I was there.
Windows team is a C++ kingdom, and those devs will not adopt .NET even at gun point.
They redid Longhorn with COM and called it WinRT, irony of ironies, WinRT applications run slower than .NET with COM reference counting all over the place.
Google has showed those folks what happens when everyone plays on the same team, and now it owns the mobile phone market, a managed userspace with 70% world market.
.NET and C# were researched a lot for operating system usage (Midori, Singularity) but that was after Longhorn.
The operating system group UI toolkits was a further problem and they pivoted there dozen of times in the years. Particular for a C++ based os group.
But the death of longhorn was ultimately about the security restart of Bill Gates
And for enums, using strings as enums was not a very efficient idea. I think JavaScript introduced Symbols for locked/hidden properties but also meant to use them as enums. It never worked either and then the sum type, union type feature of TypeScript made the whole community to keep using strings as enums. This is still a very bad idea, it is not ergonomic, it is prone to many problems, and very inefficient to compare strings instead of integers. But hey TypeScript tried to fix the problem and almost everyone rejected it. And so enum is now discontinued.
Rest of the changes to TypeScript came from almost any other language but C#, probably the biggest changes ever to happen to JavaScript came directly from CoffeeScript. And then I personally saw how each of these new changes --- one by one --- arrived at C#. For what I have seen firsthand by reading the TC39 proposals, each feature came from a different community and different programming languages, (think about null operators !/?, the nullish coalescing ??, the incoming pipes, fat arrows and lambdas, mixings) as JavaScript is the only language everyone has to use, and it has benefited everyone to have a language that has all the great things from all other languages.
The part about veering constantly to navigate the maze of internal politics is fascinating. The compromises he had to make, like not being able to put in on Github initially. The easy victories, like making TypeScript open source.
The long road to success. The obligatory advice for people writing new programming languages (Hint: Mostly, don't.). His opinion about creating a new language for AI (I agree with his insight, but still think it is possible).
Overall, well worth watching.
What's even more interesting is that Microsoft and Google were part of TC-39 at the time, and were the main opponents of ES4. While they had some rightful reasons to take this position, there's no way ES4 hasn't shaped TS in the end. Perhaps the lack of mention of any of this is due to that TypeScript might have been handed to Anders' team after the project vision and original design have developed (in the video, it is introduced as a continuation of "SharpScript"), but the interview still left me rather insatiated.
Yeah. As someone who lived that era it was so frustrating that they abandoned ES4. I used AS3 daily for almost a decade until Adobe abandoned ActionScript4 and Flash Next around 2015.
No, it was never right for public facing web sites but it shined making internal admins. HTML5 still hasn’t matched it.
EDIT: turns out Flex still lives on as Apache Royale: https://royale.apache.org/ wish I had an excuse to take it for a spin.
Around 2020, I switched into the startup space and quickly picked up TypeScript since that's "what the kids use". It wasn't without struggles, but once I wrapped my head around TypeScript as "shapes for JavaScript", it clicked.
At the time, the startup was undertaking a new product built on Nest.js[0] which looked awfully similar to ASP.NET web APIs which had the benefit of being much more mature, complete, and with one of the best ORMs (EF Core). I suggested it to the team and was a bit shocked by the pushback.
It ultimately inspired me to do a bunch of writing [1][2] on just how similar these two languages are and how they've converged on syntax (no doubt owing to Anders at the helm). Of course, they ultimately still have quite a bit of a gap, but for teams that are working in TS and finding that they are outgrowing it, C# is a very natural choice.
I left that startup after a short stint, but boomeranged almost 3 years later. Company went from seed to series C in that time. End of last year, we started the migration from TypeScript on the backend to C# on the backend and haven't looked back. The toolchain is far simpler and stable, the "default" ORM is far more flexible and powerful, the more rigorous type chain seems more conducive for agent-driven coding. Team adapted relatively quickly within ~4 weeks.
[1] https://typescript-is-like-csharp.chrlschn.dev/
[2] https://itnext.io/getting-functional-with-c-6c74bf279616
If they had a team that knows nest and can iterate fast with it that's the perfect choice. I've worked at multiple agencies over the years and was mostly in C# teams. Whenever a C# team got on greenfield/startup projects it ended up being a shit-show of self inflicted slowdowns/over-complications. I've seen 3 projects where in large part due to slow development of the MVP the project missed investment window or ran out of funds.
From my experience Node/Rails teams were much more capable of delivering shit that works. It would eventually have a bunch of problems that would be non issues by default on a different stack like ASP.NET, but the difficulty of getting to that point and realizing that just being in that situation is a win is what most engineers miss.
As he says in the video about perf "you cannot leave 10x on the table".
That's not an accurate summary. An accurate summary is that:
- They can't get the performance they want out of V8
- They're are moving to Go because its design is similar enough to JS that they can do a line-by-line port
These aren't similar claims (or mere quibbling) compared to what you wrote. They're very nearly exact opposites.
Modern C# features like `switch` expressions[2] (not `switch-case`) and pattern matching mean that it is possible to write very terse, expressive code. Extension members and methods[3] go a long way as well by making the builder pattern easier to implement.
Overall, it's up to the team to make use of the tools provided by the C# team. You can write C# in a very OOP heavy way (as is possible with TS in the case of Nest.js); you can also write in in a very functional way given many of the functional features adopted from F# over the years. It's up to the team.
[0] https://github.com/amantinband/error-or
[1] https://github.com/mcintyre321/OneOf
[2] https://timdeschryver.dev/blog/pattern-matching-examples-in-...
[3] https://typescript-is-like-csharp.chrlschn.dev/pages/interme...
C# uses exceptions for error handling. It has it's own control flow primitives. C# developers know how to work with it, everything else uses it. Why would I want to pull in a randos GH DSL and types to pretend I'm writing F# when I can just use F# that has first class support for this ?
Learning C# when you know TS is like learning Portuguese when you know Spanish.
C# syntax is fine, but has a rotten[1] culture/conventions. I suppose it makes sense that Microsoft's "Java-killer" became enterprise-y, with the same over-engineered indirections.
1. IMO - I find it very unpleasant and never allowed myself to Internalize the IConventions out of spite. YMMV.
> ...because it assumes that a C# team could have delivered the initial version in the timeline required to get to the the next level of project.
I linked the Nest.js project because you can see how similar these two are[0] with Nest.js leaning into the OOP aspects of TS at the very core. Controllers and services are classes in Nest.js, for example. It uses a somehow more complicated DI system than ASP.NET. It is Spring Boot or ASP.NET, but without the maturity, performance, and ergonomics.The team had developers that had done C# before and later hires also included former C# developers.
TS itself was new for the team at the time and several mistakes were made along the way resulting in a "dual-ORM" situation (Prisma + Drizzle; both with their faults) that ends up sapping a lot of productivity (one of the drivers to move to C#).
[0] https://typescript-is-like-csharp.chrlschn.dev/pages/interme...
In the early 2000s I have been in a startup and we delivered rapidly in C# as we did in PHP. We just coded the shit.
Problem is devs these days start from step two because we're teaching that in all sources - they never learned why it's done by doing step one - it's all theoretical example and dogma. Or they are solving problems from Google/Microsoft/etc. scale and they are a 5 people startup. But everyone wants to apply "lessons learned" by big tech.
And all this advice is usually coming from very questionable sources - tech influencers and book authors. People who spend more time talking about code than reading/writing it, and earn money by selling you on an idea. I remember opening uncle bobs repo once when I was learning clojure - the most unreadable scattered codebase I've seen in the language. I would never want to work with that guy - yet Clean Code was a staple for years. DDD preachers, Event driven gurus.
C# is the community where I've noticed this the most.
But the reality is that at some point, your FE and BE teams will diverge anyways and we use an OpenAPI spec as the contract (Nest.js, not Next.js).
So there was no benefit to using TS on both ends; only pain on the BE.
If a team is going to ship an OpenAPI spec and run it through a transformer, then it changes the selection criteria for a BE language:
- Easy for a TS team to adopt; similar core semantics like `async/await`, exception handling, etc.
- Flexible and pluggable OpenAPI spec generation for edge cases and advanced scenarios
- Excellent ORM to improve productivity around CRUD
- Good tooling
- Extensive docs, platform maturity, but modern language features
C# meets all of those in ways that no other language and platform does.Example with .NET: https://github.com/CharlieDigital/dn-kubb
I have never used any ORM that is as capable. Entity Framework Core with Linq is what keeps me on .NET.
This aspect of EF is highly underrated for complex entity graph mutations.
EF makes the 90% use case easy and the 10% case possible with very little pain. The interceptors, global conventions, and other extension points are an enabler of complex behaviors that are still transparent to most of the team.
I have never felt more understood by a fellow HN user. I think I know the exact spaghetti you are talking about, and I agree with you 100%. I wish EF could create (SQL) views, but it's not really any issue considering I can just use raw SQL to accomplish the same thing.
> complex entity graph mutations.
I'm too dumb to know what those words mean together. But I going to assume it's something to do with complex entities. If so, I completely agree as well. I sometimes harness the powers of the Dark Magics where my domain entities and database entities are the same objects (I'm not one of those DDD people either). Thanks to EF, I've been able to create some complex objects that really have cut down on a lot of useless objects I used to litter applications with.
That last one was a mistake, see https://mckoder.medium.com/the-achilles-heel-of-c-why-its-ex...
People don't have to. There is a lot of misinformation out there about checked exceptions, and people are responding to the misinformation.
- https://web.archive.org/web/20100109195800/http://windowsdev...
You can just state the author of the language is lying and you somehow know better. You don't even justify why "they don't want to acknoweldge it" - even with Hejlsberg there acknowledging taking ideas from Java - or explain why C# had those differences mentioned in the rest of that interview, or why Microsoft separately wrote their own Java implementation like Visual J++ if C# was just "their Java".
"J# does not compile Java-language source code to Java bytecode .. does not support Java applet development or the ability to host applets directly in a web browser" - https://en.wikipedia.org/wiki/Visual_J_Sharp
And, you would be stupid not to look at other languages.
How can you expect anything to be a clean slate to begin with? Is every oop language a rip off then?
Products don't get designed in a vacuum
Yeah everyone says that. He should have called out one giant specifically: James Gosling.
> And, you would be stupid not to look at other languages.
Of course. Is that really what happened here? This was a literal clone. (And it is not like Microsoft never copies competitors' products.) Yes, they did add a few features.
On the other hand Java came with the VM ("write once run anywhere" as they used to say) but C# turned that inside out with the Common Langauge Runtime, so you had various languages like C# and VB.Net that compiled to the same bytecode.
The other innovation with Java back in the day was that it came with a huge library/framework of classes that did most of the stuff you would need to do. Similarly Microsoft's .NET library was a copy of that idea, although the frameworks themselves were pretty different.
If I had to bet, I would guess VB.NET was the more popular .NET language at first. Everyone I know was converting all their ASP pages and VB apps to VB.NET.
I didn't switch from VB.NET to C# as my main language until 2021. (the 90s was all C/C++/Java for me)
For C# versus TypeScript, it's primarily the type system. You've got DUs like F#, but you also have structural typing, dependent types, linear types, refinement types, string types, and so on. It's F#'s type system on steroids IMO.
That said, C# is a great language and I use it all the time. I have a modestly popular open-source package that I write primarily in C#; I do that to make sure it's ergonomic for a C# developer first and foremost (since it's the more popular dotnet language by far) before adding in considerations for VB or F# developers like myself.
I just hope they will not overengineer and ruin it moving forward
I was there since '00.
It all started with Macromedia and their animation tool. They had an idea to add simple scripting so you add commands like "stop" or "gotoAndPlay(n)" on your animation timeline. For whatever reason they chose to use EcmaScript (aka JS).
Soon after it turned out that people were doing actual programming and shortly after in 2003 they came up with updated version called ActionScript 2.0 that added all OOP features from Java. This became the EcmaScript 4 draft.
If you ever wondered why JS has reserved keywords like "abstract", "protected" or "interface" this is why.
What's funny is that by that time the underlying engine was still working on the old ES3 so when you compiled your app your code was transpiled in exact same way TS is transpiled into JS today.
We had MXML, which was XML for laying out your controllers and classes like we do today with React and web components.
We had Alchemy that allowed you to compile C directly into Flash bytecode - exactly what emscripten is doing. And there was even a way to write assembler directly if you were brave enough.
Around 2008 there was even a thing called RedTamarin which was... command line runtime for ActionScript, just like NodeJS.
And then Apple came, Flash was gone, and with it all these things.
All of these things were erased from memory, and for the next 10 years community was slowly reinventing the wheel.
andrewstuart•5d ago
A MINIMAL memory safe language. The less it has the better.
Rust without the crazy town complexity.
The distilled wisdom from C# and Delphi and TypeScript.
A programming language that has less instead of more.
vaylian•5d ago
andrewstuart•5d ago
steve1977•5d ago
LarsKrimi•5d ago
appsoftware•5d ago
littlecranky67•5d ago
wvenable•5d ago
hirvi74•5d ago
What would you suggest instead? I quite like the nullable reference types, but I do know many get annoyed. My brain is often a scurry of squirrels, so I grew to become thankful for the nullable refs overtime.
jborean93•5d ago
wvenable•5d ago
I heavily use nullable types but I always want them to be declared nullable.
aloha2436•5d ago
To be clear, the language has a GC then?
jayd16•5d ago
AndrewDucker•5d ago
gucci-on-fleek•5d ago
ptx•5d ago
gucci-on-fleek•5d ago
andrewstuart•5d ago
gucci-on-fleek•5d ago
ahartmetz•5d ago
blackoil•5d ago
pjmlp•5d ago
rr808•5d ago
hirvi74•5d ago
rr808•5d ago
NetMageSCW•5d ago
qingcharles•5d ago
If you're talking Windows desktop apps like Delphi used to do, then Visual Studio WinForms is still just like that in 2026 and still getting updates.
tester756•5d ago
tonyedgecombe•5d ago
I do feel like there is a gap for a modern compiled, functional and garbage collected language.
Go isn't it because it lacks the functional constructs.
C# and Java aren't it because they depend on a VM.
Rust isn't it because of its difficult memory management.
Swift isn't it because it is so tied to Apple and their platforms.
kryptiskt•5d ago
trympet•5d ago
Maybe I’m being pedantic, but this is an oxymoron. Also the premise is incorrect. It’s not like the VM is gone. Merely baked into the code at compile time. It compiles IL to native code. Same for IL2CPP. The VM is still there.
The term “virtual machine” is confusing. I think you meant to say JIT compiler :-)
WorldMaker•4d ago
VMs have a long history in cross-compilation, even for "low-level" languages like C/C++. The AOT versus JIT distinction is blurry, and the "VM language" versus "non-VM language" boundary is blurrier still, especially when you take into account "standard runtimes" such as glibc and vcrt and whether or not those are statically linked.
Is a C program with a compiled with Clang through the LLVM dynamically linking a glibc and statically linking a Boehm GC library "running in a VM"? There's no wrong answer, it's a lot shades of gray. I believe almost every pedantic way to answer that has an equally pedantic counter-argument.
rednb•5d ago
Sammi•5d ago
rednb•5d ago
But it isn't a need for most use cases, unless you want to do mobile development and meet app store policies. But even then, mature F# frameworks like Fable transpile your F# code to React & Cie.
christophilus•5d ago
NetMageSCW•5d ago
EddieRingle•5d ago
jorams•5d ago
fpsvogel•5d ago
metaltyphoon•5d ago
zigzag312•5d ago
metaltyphoon•5d ago
HumblyTossed•5d ago
WorldMaker•4d ago
Sharlin•5d ago
andrewstuart•5d ago
Findecanor•5d ago
bonesss•5d ago
Contrasted with TypeScript and C#, F# is smaller, more expressive, stricter, with mature pattern matching and type resolution baked in from the ground up. F# was years ahead of the major languages on what are increasingly looking like ‘the basics’ around ADTs and immutability in modern distributed computing. OCaml and F# capture the linguistic high points of VB, Delphi, and C# with a broad spectrum of OOP(-lite) approaches, and have led those languages by decades on functional constructs that result in meaningfully tighter code. With the benefit of hindsight some approaches clearly map better to cloud computing and system verification.
F# also sits parallel to lots of living C#, objectively we see ‘less is more’. Less code per line, fewer lines per solution, terser and more LLM-efficient language. Error rates and refactoring costs are also meaningfully better IME, but harder to quantify in general terms.
christophilus•5d ago
pmkary•5d ago
pjmlp•5d ago
HumblyTossed•5d ago
hirvi74•5d ago
Don't get me wrong, I still love C#/.NET. I use it everyday, but my god, has Swift been a breath of fresh air. The Swift community, when not whining about Swift UI, has been much less dogmatic in my experience.