no surprise considering the TS people
no surprise considering the TS people
JavaScript is a cool dynamically-typed language though. C# is on another side of the spectrum: it is super cool by being fully strongly-typed. But TypeScript is something in the middle and this uncertainty gives pains.
Not really.
For personal projects or if you're a freelancer sure. Once you work in a company/startup you can't go and implement things in whatever you like.
It's way easier to convince any manager that Dart/Flutter is a good choice for a mobile app because of the tech advantages than in anything else because of the pool of available developers.
Standard library that isn't worthless - no more npm package spam.
Type knowledge in the runtime. It doesn't have to be typed, just make it so I don't have to do crazy checks on properties before casting to a class.
Imports without webpack.
You do have 'instanceof' at runtime, so unless you mean some other type of 'class', casting to a class is really a non-issue (and you don't really 'cast'... since dynamic typing and all). If you mean some more advanced concept (e.g., structural type runtime checking), think how you would do it in statically typed languages (is it really better?).
function Foo(s) {
this.s = s
}
Foo.prototype.bar = function() {
console.log(this.s)
}
const baz = new Foo("Baz")
baz.bar()
But it seems Typescript can't handle it?(1) imperative style mutation of the prototype is runtime dependent, and typescript can't really rely on runtime behavior.
(2) Foo has two incompatible types in JS, it is both `(s) => void` and `new (s) => Foo`, typescript by default will assume the first signature (which is usually what people want).
In any case, you can specify the types (though in 99% of the cases, just use a class):
interface Foo {
s: string;
bar(): void;
}
const Foo = function(this: Foo, s: string) {
this.s = s;
} as {
new (s: string): Foo;
(this: Foo, s: string): void;
};
Foo.prototype.bar = function(this: Foo) {
console.log(this.s);
}
const baz = new Foo('Hello');
baz.bar()While that is a fair statement, I've been reading a lot of Typescript code lately and it seems in 99% of cases the selected solution is to use top level functions and globals to avoid the nesting hell class introduces, albeit introducing the global hell in the process. In practice, 'just use a class' doesn't overcome the human element.
Javascript was on the right track originally, but then veered off into the weeds for some reason. I appreciate you pointing out how it can be done. Although the solution is very much second class citizen, sadly. This certainly isn't going to wean developers away from global hell. Hopefully Javascript/Typescript can make some strides in improving this going forward.
We are talking about runtime class creation with dynamic methods, while still adding proper static types. There aren't many language allow this level of flexibility.
You can probably disallow prototype use with existing tools if that's desired, but it is an advanced tool for advanced use cases (which still exist).
Given:
class Foo {
constructor(x) {
this.x = x
}
bar() {
return this.x
}
}
maybe it becomes: object Foo(x) {
this.x = x
}
function Foo.bar() {
return this.x
}This is exactly what bugs me about TypeScript. The language itself is fine—some annoying things, but generally they’re due to having to run on top of JS. But Microsoft had the chance to fix JS’s terrible standard library. And they didn’t!
I know that's less of a concern nowadays with modern http, but guess who still supports ie11
It feels like terrible advice to give someone, given ESM is far superior to AMD, and this would be going backwards in time, but in your case you are already blighted by the disease and it is advice that might staunch some of the bleeding.
Here's a snippet of C# I wrote recently to transform some JSON:
var transformed = media.Select(m => {
var parts = m.Split('/');
return new {
addedAtUtc = "2023-05-15T05:59:31.398Z",
originTripUid = parts[4],
path = $"{parts[4]}/{parts[5]}",
rank = "",
size = 103978,
stored = true,
type = "document",
};
})
File.WriteAllText(
Path.Combine(Environment.CurrentDirectory, "output.json"),
System.Text.Json.JsonSerializer.Serialize(transformed)
);
It would be easy to mistake this as JS at a quick glance.Duck Typing at runtime is possible and to a degree checkable and compile-time.
var transformed = media.Select(m => {
var parts = m.Split('/');
return new {
addedAtUtc = "2023-05-15T05:59:31.398Z",
originTripUid = parts[4],
path = $"{parts[4]}/{parts[5]}",
rank = "",
size = 103978,
stored = true,
type = "document",
};
}).ToList();
transformed.AddRange(otherMedia.Select(m => {
var parts = m.Split('/');
return new {
addedAtUtc = "2023-05-15T05:59:31.398Z",
originTripUid = parts[4],
path = $"{parts[4]}/{parts[5]}",
rank = "",
size = 103978,
stored = true,
type = "document",
documentType = parts[6]
};
}));
Adding "documentType" breaks in C# but would work in a structurally typed language as a structural type checker can see that the second result fulfills all of the necessary properties. Doing this in C# would require creating an interface and being explicit.Function dispatch: TS is purely dynamic; C# has both static and dynamic
OOP: Mandatory in C#, optional in TS
Variance: Implicit in TS, explicit in C#
Numeric types: TS has one (number); C# has the entire signed/unsigned/float x 8/16/32/64-bit matrix
There's really no intentional effort to converge them.
[0]: https://www.typescriptlang.org/docs/handbook/2/everyday-type...
JS already has 'with', so 'using' seems like to closest semi-standard keyword to use.
But since TS is supposed to be a superset of JS, of course this does not change anything