I made a quick version of this idea in Python 3.4, where it was much easier since I could modify the AST on import, but I never quite got it where I wanted it and sort of lost passion.
I made a quick version of this idea in Python 3.4, where it was much easier since I could modify the AST on import, but I never quite got it where I wanted it and sort of lost passion.
The old Visual Studio Javascript autocomplete engine apparently worked in a similar way to what you suggest, running the code in a sandbox and then analysing the types, but they've now moved to a static engine (which I think is also used in VS Code?) - some information at https://blogs.msdn.microsoft.com/visualstudio/2016/04/08/pre...
function incrX(obj) {
obj.x += 1
}
We can infer incrX expects an object with property x, which is probably an integer. And therefore, a call like `incrX({x: "hello"})` is probably incorrect. In fact, I think this is how type inference in languages like OCaml works.That said, I do wish statically-typed languages generally had runtime type checking built in. For instance, I can tell Typescript what type of response we're expecting to get from an API call, but that doesn't mean the compiled Typescript will warn me if the API call ends up with a different type.
Except OCaml's typing is much stricter than JS's, in JS `obj.x += 1` is perfectly valid if `x` is a string. In fact due to all the runtime type conversion protocols you can have pretty much anything as `x` and have `obj.x += 1` succeed.
So that requires a strict break and separation with JS semantics and treating JS (or whatever) as an implementation detail and "assembly", which is the opposite of Typescript's purpose (it's more of an Elm or Purescript or ocaml_in_js thing)
> That said, I do wish statically-typed languages generally had runtime type checking built in.
Statically typed languages with lots of holes (at the type-system level) like Java or C# do have runtime checks. Those with less holes like OCaml or Haskell don't as the only way to get the "wrong" types at runtime is to have wilfully undermined the type system in which case the developer is on the hook for making sure they do that correctly.
> For instance, I can tell Typescript what type of response we're expecting to get from an API call, but that doesn't mean the compiled Typescript will warn me if the API call ends up with a different type.
That would require TypeScript having its own runtime rather than compiling to regular Javascript, or it would require that TypeScript inject a fuckton of type checks which would make the output orders of magnitude slower (both from the overhead of javascript-level type-checking and from the increase in code size and decrease in JIT optimisation opportunities).
This has a very annoying side effect of never being able to exclude interfaces from a union type:
function doStuff(thing : string | SomeInterface) : void {
if (typeof(thing) === "string") {
// thing is still typed as string | SomeInterface,
// because there's no guarantee that the
// string object doesn't implement the interface.
// If SomeInterface was a class instead of an interface,
// then thing would only have the string type here.
}
}
Also, this is ignoring the fact that you would also need to check the parameter types on an incoming function, which AFAIK isn't possible at all.http://www.typescriptlang.org/play/#src=interface%20SomeInte...
if (typeof(x) === "string")
I opened an issue: https://github.com/Microsoft/TypeScript/issues/9391Thanks for the help!