8 ms·
> in many cases being unable to import a JS library in that doesn't include typedefs Make sure you have "allowJs": true in your tsconfig.json. Otherwise, you'l
by phiresky 7y ago
> in many cases being unable to import a JS library in that doesn't include typedefs
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.
- Dylan16807 7y agoThis doesn't need magic powers. All you have to do is treat literal values inside type descriptions differently.
- phiresky 7y agoInside of type descriptions, literal values are always treated as literals. The problem only appears when you declare a variable _without_ an explicit type like `const foo = {k: 'x'}`, which the compiler then infers to be of type `foo: {k: string}` and not `foo: {k: 'x'}`. 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}`.
- Dylan16807 7y agoSo the example of `false | 'x' | 'y' | undefined` turning into string is invalid? I feel like I'm missing something.
- phiresky 7y agohere's a full example. If you do this: 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)
- Dylan16807 7y agoThanks!
- Rapzid 7y agoDidn't realize "as const" worked; will have to try that next time.
- ElFitz 7y ago> There is no other programming language that has union types as powerful as TypeScript How about Swift and OCaml? ReasonML comes to mind too. Haven't tried actively comparing any of them though.
- tomp 7y agoOCaml/Reason have discriminated unions, which means that you have to explicitly specify which variant of the union you're using, such as type union = Bool of bool | Char of char | Nothing let (x, y, z) = (Nothing, Bool true, Char 'x')
- saagarjha 7y agoIs this not what enums with associated values are?
- tomp 7y agoProbably... but in any case TypeScript also supports naked (edit: I just made up the name) unions, where you don't need to declare them upfront, and where values of different types can be included directly. Such as: let a = random() ? 'a' : 1 TypeScript infers type string | number
- marton78 7y agoThis is still a discriminated union, only that the discriminator is provided by Javascript and is thus hidden: it's `typeof`.
- tomp 7y agoYeah, that's the runtime perspective... but for the type system, they're different... with the "naked" union being much harder (as they're non-algebraic - `a | b | b` always equals `a | b` and might even equal just `a` for some values of `a` and `b`)
- 7y ago
- phillipcarter 7y ago> There is no other programming language that has union types as powerful as TypeScript I suggest looking into Idris and other languages with dependent types. Nothing against typescript, but it’s not even close.
- logicchains 7y agoIdris doesn't have anonymous sum types, nor does Coq or Lean. Which language were you thinking of?
- phillipcarter 7y agoCeylon comes to mind; haven't googled others.
- shakna 7y ago> There is no other programming language that has union types as powerful as TypeScript 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 https://en.m.wikibooks.org/wiki/Ada_Programming/Types/record