Alternative for visitor pattern in TypeScript (avoiding instanceof conditionals)

You can use the approach the typescript compiler team used and have a field that discriminates against the type of field, replacing instanceof with a simple string/number comparison, which is probably less expensive (although you should test for your use case):

enum Types {
    A, B
}
interface I <T extends InternalResult> {
    readonly type : Types;
    doStuff(): T;
}
class A implements I <AResult> {
    readonly type =  Types.A
    doStuff(): AResult {
        return new AResult();
    }
}

class B implements I <BResult> {
    readonly type =  Types.B
    doStuff(): BResult {
        return new BResult();
    }
}
class Visitor {
    private aExecuter: AExecuter = new AExecuter();
    private bExecuter: BExecuter = new BExecuter();

    visit(it: A | B): AResult | BResult {
        // Since we don't have a default return, we will get a compiler error if we forget a case
        switch(it.type){
            case Types.A : return this.aExecuter.execute(it); break;
            case Types.B : return this.bExecuter.execute(it); break;
        }
    }
}

Another approach which requires less writing (but is less type safe) is to use the constructor name as a key for access the correct method:

class Visitor {
    private aExecuter: AExecuter;
    private bExecuter: BExecuter;

    visit(it: A | B): AResult | BResult {
        let visitor: (it: A | B) => AResult | BResult = (this as any)['visit' + it.constructor.name];
        if(visitor == null) {
            throw "Visitor not found"
        }
        return visitor.call(this, it)
    }
    visitA(it: A): AResult {
        return this.aExecuter.execute(it);
    }

    visitB(it: B): BResult {
        return this.bExecuter.execute(it);
    }
}