> For example, How can I check that a given var is a Array<Int> ?
var a:Array<Int>;
You have two choices here: If class (in your case Array) is @:generic
trace(Std.string(a)); // traces Array_Int
trace($type(a)); // traces [Object Array_Int];
However, in most cases, your (or external class) is not @:generic. In that case you can use macro 
class CTTI { //compile time typo info
    @:macro
    public static function get_type(instance) {
        var b:Dynamic;
        switch(Context.typeof(instance)) {
            case TType(t, p): b = t.get().name;
            case TInst(i, p): // b = i.get().name;
                switch(p[0]){case TInst(c,d): b=c.get().name;
                            default:null;};
            case TDynamic(d): b="dyn";
            case TAnonymous(a): b="anon";
            case TMono(m): b="mono";
            default: b=null;
        }
        return Context.makeExpr(b, haxe.macro.Context.currentPos());
    }
}
You can use it like
        var c:String = CTTI.get_type(a);
        trace("macro: " + c);
Since macros are executed at compile time, you can use macro output for static variables (where applicable), etc.
Important: you can't observe type parameter inside the class which implements it (not without live instance).