Implementing a generic Comparator
Personally, because this function can be simplified, I don't believe the variables are necessary. Since you are using Typescript, an enum would fit well here, but I believe even this is unnecessary. The results of a compare function are well standardized.

enum Result {
  equal = 0,
  greater = 1,
  lesser = -1
}


You are correct that it is more appropriate to apply the function with generics. If somewhere you need the flexibility that any provides, you can simply call the function with compare&lt;any&gt;(a, b) to override the type. I personally have found that any is only useful when first converting a project and will avoid it like the plague if at all possible.

Now, a few comments about the function itself. 


I'm not sure how you are compiling this, but it emits three errors in the playground.


nullOrUndefined(s1) ^ nullOrUndefined(s2) - The '^' operator is not allowed for boolean types. Consider using '!==' instead.
s1 = s1.toLowerCase();- Type 'string' is not assignable to type 'T'.
s2 = s2.toLowerCase(); - Property 'toLowerCase' does not exist on type 'T'.

You will have problems if you try to use this function with the built in Array.prototype.sort function because undefined results in the array being treated as a sparse array. See the spec.
To ignore string case, it would be better to use String.prototype.localeCompare. 


Here is how I would implement this function. I purposely use == instead of === for comparing null as it also catches undefined.

function compare&lt;T&gt;(a: T, b: T): number {
    if (a == b) return 0;
    if (a == null) return -1;
    if (b == null) return 1;

    // To appease the type system, check both
    // I think it might be a bug that this is required
    if (typeof a === 'string' &amp;&amp; typeof b === 'string') {
        return a.localeCompare(b, 'standard', { sensitivity: 'case'});
    }

    return b &gt; a ? -1 : 1;
}