(no title)
emn13 | 9 months ago
1. Flowsensitivity: It's a sure thing that in a dynamic language people use coding conventions that fit naturally to the runtime-checked nature of those types. That makes flow-sensitive typing really important.
2. Duck typing: dynamic languages and certainly ruby codebases I knew often use ducktyping. That works really well in something like typescript, including really simple features such as type-intersections and unions, but those features aren't present in C#.
3. Proof by survival: typescript is empirically a huge success. They're doing something right when it comes to retrospectively bolting on static types in a dynamic language. Almost certainly there are more things than I can think of off the top of my head.
Even though I prefer C# to typescript or ruby _personally_ for most tasks, I don't think it's perfect, nor is it likely a good crib-sheet for historically dynamic languages looking to add a bit of static typing - at least, IMHO.
Bit of a tangent, but there was a talk by anders hejlsberg as to why they're porting the TS compiler to Go (and implicitly not C#) - https://www.youtube.com/watch?v=10qowKUW82U - I think it's worth recognizing the kind of stuff that goes into these choices that's inevitably not obvious at first glance. It's not about the "best" lanugage in a vacuum, it's a about the best tool for _your_ job and _your_ team.
usernamed7|9 months ago
Another commenter suggested another language like crystal, and that might actually be what it really needs, a ruby-like alternative.
emn13|9 months ago
Kinrany|9 months ago
emn13|9 months ago
I think it's pretty usuable now, but there is scarring. The solution would have been much nicer had it been around from day one; especially surrounding generics and constraints.
It's not _entirely_ sound, nor can it warn about most mistakes when those are in the "here-be-dragons" annotations in generic code.
The flow sensitive bit is quite nice, but not as powerful as in e.g. typescript, and sometimes the differences hurt.
It's got weird gotcha interactions with value-types, for instance but likely not limited to interaction with generics that aren't constrained to struct but _do_ allow nullable usage for ref types.
Support in reflection is present, but it's not a "real" type, and so everything works differently, and hence you'll see that code leveraging reflection that needs to deal with this kind of stuff tends to have special considerations for ref type vs. value-type nullabilty, and it often leaks out into API consumers too - not sure if that's just a practical limitation or a fundamental one, but it's very common anyhow.
There wasn't last I looked code that allowed runtime checking for incorrect nulls in non-nullable marked fields, which is particularly annoying if there's even an iota of not-yet annoted or incorrectly annotated code, including e.g. stuff like deserialization.
Related features like TS Partial<> are missing, and that means that expressing concepts like POCOs that are in the process of being initialized but aren't yet is a real pain; most code that does that in the wild is not typesafe.
Still, if you engage constructively and are willing to massage your patterns and habbits you can surely get like 99% type-checkable code, and that's still a really good help.
uticus|9 months ago
neonsunset|9 months ago
For the best experience you may want to add `<WarningsAsErrors>nullable</WarningsAsErrors>` to .csproj file.