facebook / flow

Adds static typing to JavaScript to improve developer productivity and code quality.
https://flow.org/
MIT License
22.07k stars 1.86k forks source link

Class union type refinement takes too long. #5188

Open Zmetser opened 6 years ago

Zmetser commented 6 years ago

Refining an union of class that share a common base takes a lot longer than it should. Especially, when the refining code has conditions like this instance instanceof AA || instance instanceof AB.

Here's a code example that will still run in the online sandbox:

// @flow
class Base {}

class A extends Base {}
class AA extends Base {}
class AB extends Base {}
class B extends Base {}

type ClassUnion = A | AA | AB | B;

function test(instance: ClassUnion): ?string {
    if (instance instanceof A) return 'A'
    else if (
        instance instanceof AA ||
        instance instanceof AB
    ) return 'ASomething'
    else if (instance instanceof B) return 'B'
    else unexpectedCase(instance);
}

function unexpectedCase(impossible: empty): void {
    throw new Error(`Unexpected case ${impossible}`);
}

Here's one that takes 10s to run, freezes the online sandbox and always does a merge on flow check regardless of what changed. (looks like the real deciding factor is not the number of is statements but the number of conditions in an if statement.)

Zmetser commented 5 years ago

Union refinement is still slow as of v0.86.0.

Try it here

The workaround is to have all check in a new else if condition