Safety bypasses should be opt-in, case by case, and very explicit. For example, Rust's `unsafe` allows bypassing any limitation the language safety imposes on you normally, but all code not explicitly labeled unsafe is always in the very very safe mode.
Even inside the Typescript rules, `as` is a ridiculously dangerous timebomb.
Typescript is 100% about "convenience" and write-lots-of-code-now style of productivity, ~0% about safety or long-term maintainability.
What's the big difference between `unsafe` and `as` regarding explicit labelling? Both are opt-in and explicit. As the user of a function, you don't see either from the outside. If you don't like `as`, it's fine to use a linter to disallow it.
The difference is that in everyday Typescript you end up using `as`, so it's presence is not a blaring alarm.
Grepping a real world codebase that would not be `unsafe` in Rust:
event as CustomEvent<T>
const errorEvent = event as ErrorEvent;
const element = getByRole("textbox");
expect(element).toBeInstanceOf(HTMLInputElement);
const input = element as HTMLInputElement;
const element = parent.firstElementChild as HTMLElement;
type ItemMap = Map<Item["id"], Item>;
...
new Map() as ItemMap
const clusterSource = this.map.getSource(sourceName) as GeoJSONSource;
[K in keyof T as T[K] extends Fn ? K : never]: T[K];
target[type] as unknown as Fn<...
export const Foo = [1,2,3] as const;
and on it goes. Typescript normalizes unsafe behavior. Many, if not most, of these occurrences can be made safe. It's very rare that I need `as`, and even more rare that I can't actually check the relevant properties at runtime to ensure the code path is valid.
It's on you to ensure that you don't misuse `as`. If I could choose between current TS, and a "safer" one that's less expressive in complex cases, I'd choose the current one any day of the week.
"Typescript can be made safe" is the "C++ has a subset that is good" argument. Meh.
Almost every language has some way to do stupid things. Say you're working in C# - you can forcefully cast almost anything to almost anything else, just like in TS. So according to you, C# is just as bad as TS in this respect, right?
You can only do this with `unsafe { }` or `Unsafe.As/.BitCast`. Casts from/to `object` are type-safe even though may not be very user-friendly or good use of the type system in general.
If that's a thing commonly needed for basic operations like letting your event handler actually access the event details, then very much yes.
Sane languages have a downcast mechanism that doesn't pretend it succeeds every time.
Weird, I don't need to do that.
Also weird that Typescript has exactly the mechanism you're talking about. Why are you acting like it doesn't?