Let me share with you a way to achieve what I think you are aiming for (please let me know if there are any corrections needed)
type IfAny<T, Y, N> = 0 extends (1 & T) ? Y : N;
type IfAnyArray<T, Y, N> = T extends ReadonlyArray<infer V> ? IfAny<V, Y, N> : N;
type IsAnyArray<T> = IfAnyArray<T, 'is any[]', 'is not any[]'>
type test_fooz = IsAnyArray<(number | string)[]>
// ^?
type test_foo0 = IsAnyArray<number[] | string[]>
// ^?
type test_foo1 = IsAnyArray<string[]>
// ^?
type test_foo2 = IsAnyArray<any[]>
// ^?
type test_foo3 = IsAnyArray<readonly string[]>
// ^?
type test_foo4 = IsAnyArray<readonly any[]>
// ^?
type test_foo5 = IsAnyArray<MyArray<string>>
// ^?
type test_foo6 = IsAnyArray<MyArray<any>>
// ^?
type test_excb = IsAnyArray<(string & {brand: 'myBrand'})[]>
// ^?
type test_excB = IsAnyArray<(string & {brand?: 'myBrand'})[]>
// ^?
class MyArray<T> extends Array<T> {
x!: number;
}
If you're looking into using Exclude
, here's how:
type ExcludeArrayOf<T, E> = T extends ReadonlyArray<infer V extends E> ? IfAny<V, T, never> : T;
type test_excz = ExcludeArrayOf<(number | string)[], string>
// ^?
type test_exc0 = ExcludeArrayOf<number[] | string[], string>
// ^?
type test_exc1 = ExcludeArrayOf<string[], string>
// ^?
type test_exc2 = ExcludeArrayOf<any[], string>
// ^?
type test_exc3 = ExcludeArrayOf<readonly string[], string>
// ^?
type test_exc4 = ExcludeArrayOf<readonly any[], string>
// ^?
type test_exc5 = ExcludeArrayOf<MyArray<string>, string>
// ^?
type test_exc6 = ExcludeArrayOf<MyArray<any>, string>
// ^?
type test_excb = ExcludeArrayOf<(string & {brand: 'myBrand'})[], string>
// ^?
type test_excB = ExcludeArrayOf<(string & {brand?: 'myBrand'})[], string>
// ^?