//// [controlFlowInstanceof.ts]

// Repros from #10167

function f1(s: Set<string> | Set<number>) {
    s = new Set<number>();
    s;  // Set<number>
    if (s instanceof Set) {
        s;  // Set<number>
    }
    s;  // Set<number>
    s.add(42);
}

function f2(s: Set<string> | Set<number>) {
    s = new Set<number>();
    s;  // Set<number>
    if (s instanceof Promise) {
        s;  // Set<number> & Promise<any>
    }
    s;  // Set<number>
    s.add(42);
}

function f3(s: Set<string> | Set<number>) {
    s;  // Set<string> | Set<number>
    if (s instanceof Set) {
        s;  // Set<string> | Set<number>
    }
    else {
        s;  // never
    }
}

function f4(s: Set<string> | Set<number>) {
    s = new Set<number>();
    s;  // Set<number>
    if (s instanceof Set) {
        s;  // Set<number>
    }
    else {
        s;  // never
    }
}

// More tests

class A { a: string }
class B extends A { b: string }
class C extends A { c: string }

function foo(x: A | undefined) {
    x;  // A | undefined
    if (x instanceof B || x instanceof C) {
        x;  // B | C
    }
    x;  // A | undefined
    if (x instanceof B && x instanceof C) {
        x;  // B & C
    }
    x;  // A | undefined
    if (!x) {
        return;
    }
    x;  // A
    if (x instanceof B) {
        x;  // B
        if (x instanceof C) {
            x;  // B & C
        }
        else {
            x;  // B
        }
        x;  // B
    }
    else {
        x;  // A
    }
    x;  // A
}

// X is neither assignable to Y nor a subtype of Y
// Y is assignable to X, but not a subtype of X

interface X {
    x?: string;
}

class Y {
    y: string;
}

function goo(x: X) {
    x;
    if (x instanceof Y) {
        x.y;
    }
    x;
}

//// [controlFlowInstanceof.js]
// Repros from #10167
function f1(s) {
    s = new Set();
    s; // Set<number>
    if (s instanceof Set) {
        s; // Set<number>
    }
    s; // Set<number>
    s.add(42);
}
function f2(s) {
    s = new Set();
    s; // Set<number>
    if (s instanceof Promise) {
        s; // Set<number> & Promise<any>
    }
    s; // Set<number>
    s.add(42);
}
function f3(s) {
    s; // Set<string> | Set<number>
    if (s instanceof Set) {
        s; // Set<string> | Set<number>
    }
    else {
        s; // never
    }
}
function f4(s) {
    s = new Set();
    s; // Set<number>
    if (s instanceof Set) {
        s; // Set<number>
    }
    else {
        s; // never
    }
}
// More tests
class A {
}
class B extends A {
}
class C extends A {
}
function foo(x) {
    x; // A | undefined
    if (x instanceof B || x instanceof C) {
        x; // B | C
    }
    x; // A | undefined
    if (x instanceof B && x instanceof C) {
        x; // B & C
    }
    x; // A | undefined
    if (!x) {
        return;
    }
    x; // A
    if (x instanceof B) {
        x; // B
        if (x instanceof C) {
            x; // B & C
        }
        else {
            x; // B
        }
        x; // B
    }
    else {
        x; // A
    }
    x; // A
}
class Y {
}
function goo(x) {
    x;
    if (x instanceof Y) {
        x.y;
    }
    x;
}
