4 ms·
> there's no runtime assurance that a string is actually a string. As someone who's written a lot of Typescript in fairly large projects: in practice this isn'
by p1necone 2y ago
> there's no runtime assurance that a string is actually a string.
As someone who's written a lot of Typescript in fairly large projects: in practice this isn't really an issue if you
1. ban casting and 'any' via eslint,
2. use something like io-ts at http api/storage boundaries to validate data coming in/out of your system without a risk of validator/type mismatch.
But you have to have total buy in from everyone, and be willing to sit down with new devs and explain why casting is bad, and how they can avoid needing that eslint suppression they just added to the codebase. It certainly would be easier if it just wasn't possible to bypass the type system like this.
- mubou 2y agoI know, but it's that last bit: it shouldn't be possible to bypass it. C# actually got itself into a similar issue despite being a proper static language, because when it added "nullable reference types" (where you can't assign null to a variable of type `Foo` unless it's explicitly typed as `Foo?`) they did it like TypeScript using purely static analysis to avoid having to change the language at a lower level (for compatibility). Even though it works 99% of the time, just like in TS you can occasionally run into a bug because some misbehaving library handed you a null that it said can't be a null...
- Timon3 2y agoOn the other hand, disallowing bypassing it limits what you can do. There's always a ceiling to what the compiler can figure out, and some very complex types can't be analysed statically right now. By allowing bypassing the system, I can still accurately type those functions and reap all the rewards, and I can make sure everything works by combining unit tests with type unit tests. If bypassing was disallowed, I'd be more limited in what I can express.
- yencabulator 2y agoSafety 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.
- Timon3 2y agoWhat'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.
- yencabulator 2y agoThe 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.
- Timon3 2y agoMany, 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.
- yencabulator 2y ago"Typescript can be made safe" is the "C++ has a subset that is good" argument. Meh.
- Timon3 2y agoAlmost 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?