Generic argument constrained to be non array

Viewed 115

is there a way to say that passed type argument of a method cannot be an array??

example class

class A {
  public f<T /*which is not array*/>(obj: T) { /* ... */ }
}

This code would not be compiled:

const a = new A();

a.f<number[]>([42, 42]);
1 Answers

Yes, there is:

class A {
  public f<T>(obj: T extends Array<any> ? never : T) { /* ... */ }
}

const x = new A();
x.f(1) // ok
x.f([]) // error
x.f([1]) // error

Btw, there is no negation type in TypeScript. For instance, you can't write smth like: not Array<any> or !Array<any>, but TS has conditional types.

In my example I'm returning never if argument is Array.

What does it mean?

It is mean, that TS will expect one argument with never type.

The trick is, that you can't produce never type literally.

You can create your own negation type:

type Not<T,  R> =  R extends T ? never: R;

Thanks @Eldar !

Related