Ada's record [0] type stands out. From what I can see, TS' unions are not nearly as powerful.
[0] https://en.m.wikibooks.org/wiki/Ada_Programming/Types/record
I suggest looking into Idris and other languages with dependent types. Nothing against typescript, but it’s not even close.
How about Swift and OCaml? ReasonML comes to mind too. Haven't tried actively comparing any of them though.
type union = Bool of bool | Char of char | Nothing
let (x, y, z) = (Nothing, Bool true, Char 'x') let a = random() ? 'a' : 1
TypeScript infers type string | numberI merely know from experience that they have a pretty good type system, but not much more. So I asked :-)
Answers have been enlightening
Both of these are valid inferences, and it's impossible to know which one the user wants in the general case, which is why you have to explicitly say `const foo = {k: 'x' as const}`.
I feel like I'm missing something.
function test(p: {k: false | 'x' | 'y' | undefined}) {
// do stuff
}
const p = {k: 'x'} // inferred type: {k: string}
//...
test(p); // type error : Type 'string' is not assignable to type 'false | "x" | "y" | undefined'
The problem is that the type of p.k is inferred to `string` not `x`. The compiler can't know this is fine because you could call `foo(p)` in between the declaration and the `test` call, that mutates p.k.If you add `as const` or an explicit type to p it is fine.
(I think this is what the GGP was referring to)
Make sure you have "allowJs": true in your tsconfig.json. Otherwise, you'll have to create a minimal file with `declare module "xyz";`
> I fail to see how TS can be considered a superset of JS
You have to interpret all TS "errors" as warnings for that to be true (which they mostly are considering tsc still emits code regardless of non-syntax-error errors)
> I just cannot take a type system seriously when workarounds like that are needed.
Your problem really just seems to be that the type inference does not have magical powers. There is no other programming language that has union types as powerful as TypeScript (as in discriminating by whatever you want), but yeah when you do `return {x: 1, y: 2}` the compiler doesn't always know whether you mean to return an object where the type of x is `1` or where it is `number`. In some cases it could be better still, but doing this in general is just not possible.