3 ms·
In particular, supporting nominal typing, fixing the way index types work, and fixing the story of debugging type failures on giant unions come to mind, but the
by ajkjk 4y ago
In particular, supporting nominal typing, fixing the way index types work, and fixing the story of debugging type failures on giant unions come to mind, but there are countless others. (Don't @ me, my day job is a few versions behind and I can't remember what's in the latest version, but there are plenty of other things if not these.)
- culi 4y agoYeah I think the new `satisfies` operator and improvements to type inferences in the latest version likely resolve a lot of your concerns. TypeScript also supports some really advanced typing I've yet to see in other languages like template literal types (don't @ me, I mostly work with dynamic languages at my current job). I feel like even the TS docs haven't caught up to the full power of TS's full featureset
- svieira 4y agoFYI, TypeScript already supports nominal types, but the ways in which you "spell" `nominal` are a little unintuitive: 1. Use an enum 2. Use an intersection with an enum and literally anything else (except a number) 3. Use a private field (only works with classes) 4. Use a `declare const FOO: unique symbol` keyed object intersected with anything else (works with everything including numbers, lots of boilerplate to declare a new nominal type).
- ajkjk 4y agoI'm aware of some of those, but I think they're all suboptimal compared to actual nominal types. In particular iirc you can't use your nominal/branded type as a map key in a type-safe way.
- scotty79 4y agoNot sure what you mean: enum A {} type B = { a: number } & A; function newB(i:number) { return { a: i } as B; } let b:B = newB(5); let m:Map<B, string> = new Map(); m.set(b, "test"); m.set({ a: 2 }, "test"); // errors
- svieira 4y agoWhat he means is that you didn't _used_ to be able to do this: declare const NOMINAL_BRAND: unique symbol; enum UserIdType {} type UserId = string & {[NOMINAL_BRAND]: UserIdType} type UserMap<V> = { [key: UserId]: V }; But at some point in the past few years, this is now supported and things like this work as expected: const userId: UserId = "234" as UserId const coolUsers: UserMap<boolean> = {} coolUsers[userId] = true // works coolUsers["isThisOkay"] = false // fails
- ajkjk 4y agoInteresting, I thought that wasn't possible, but now I feel like I'm just confused and mixing it up with something else that wasn't possible but can't remember well enough. But anyway, what I want from TS is type UserId = unique string; // or something const userId = "1234" as UserId and no further boilerplate or trickery to get it to work. Would certainly be nice.
- scotty79 4y agoYou can get close to that: https://github.com/seancroach/ts-opaque https://github.com/seancroach/ts-opaque
- no_wizard 4y agoyou could use a WeakMap to emulate private fields too
- the_duke 4y agoMy biggest wish would be proper sum types. The current way of manually creating tagged unions is really awkward. But that won't be added because there is no native JavaScript equivalent.
- ajkjk 4y agoI wouldn't rule it out. They seem to be increasingly amenable to ergonomic changes that are less coupled to what JS would do in my impression.
- scotty79 4y agoI think it can be safely ruled out. TypeScript tenet which they consistently uphold is that types can't influence behavior of the running code. So to differentiate behavior depending of which part of sum type you got you need some value in the "real world" like a tag that can enable you to do that. Because all the type information is gone at runtime. Strongest violation of this rule I know of are enums that generate their own JS code, but they are their separate thing. Something like sum types would need to be present everywhere. Honestly I kind of like it this way. I'm trying out Rust right now and I'm very often surprised how what I do in one spot depends on huge context of all the generic types that can create wildly different behavior (mostly huge variety compile type error messages in surprisingly varied and distant spots) depending on what types they infer.