Skip to content

Thesis on improved type system #5168

Closed
Closed
@ivogabe

Description

@ivogabe

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:

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:

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:

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 (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:

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    DiscussionIssues which may not have code impact

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions