Hi everyone, I'm currently starting my bachelor thesis, as part of the Honours Program at the University of Utrecht. The subject will be something with type inference in TypeScript. The final product - besides the written thesis - will be an implementation of the algorithm in TypeScript. My plan is to fork the TypeScript compiler, and it'd be great if my changes would be merged into TypeScript. My subject is not yet fixed, so I'd like to discuss here which subject would be most suitable. Here are the two ideas I've got: ## 1 - Control flow based typeguards. Example: ``` typescript let x: string | number = ...; if (typeof x === number) { // x: number x = x.toExponentional(); // x: string } else { // x: string x = x.substring(1); // x: string } // x: string console.log(x.substring(1)); ``` A different kind of type guards could be implemented like this: ``` typescript function expectString(x: any) x as string { if (typeof x !== 'string') { throw new Error('Expected string, got ' + typeof x); } } let x: string | number = ...; // x: string | number expectString(x); // x: string ``` This typeguard can be useful when checking the provided arguments in for instance a nodejs server or a public api. ## 2 - Improved inference using function bodies Example: ``` typescript function square(x) { return x * x; } // Current: square(x: any): number // Expected: square(x: number): number function squareLength(x, y) { return square(x) + square(y); } // Current: squareLength(x: any, y: any): number // Expected: squareLength(x: number, y: number): number ``` Dificulties are polymorphic functions (like the identity function `(x) => x`) and recursive functions. Algorithms that can handle these functions exist (Cartesian Product algorithm or (Extended) Monotone Framework). Such algorithm has been [implemented for PHP](http://dspace.library.uu.nl/handle/1874/309754) (without type annotations, only the standard library had hard coded types). This would also be useful for editors which use the language services for JavaScript code, as a lot more types can be inferred. Support for objects will be limited (see below), given the time for my thesis. Limited support for objects is probably good for performance, too. Overall performance will depend on the precision, in some cases we can for example fallback to any to get reasonable performance. Limited support for objects means that methods, that could be part of an object on the heap, won't be tracked, like the following example: ``` typescript declare class A { foo(): string; } declare class B { foo(): number; } let x; let y = x.foo(); ``` The algorithm in the PHP implementation would infer `y` to `string | number`. Not supporting this means y is typed as `any`, which would have my preference, as it would fit better in TypeScript. I haven't chosen a specific algorithm yet, I'd like to get some 'requirements' to choose one, for instance, what should happen with recursive functions (a function might call itself, or a function `f` might call `g`, that might call `f`). I'd like to get some feedback on these ideas. Would you be interested in merging these two, or one of these, into the compiler? Or do you have some related suggesions that I could implement?