L
L
lightalex2020-11-30 02:16:11
Data types
lightalex, 2020-11-30 02:16:11

How to exclude a specific class from a type in Typescript?

There is the following code:

type BaseType<T> = { new(): T };

class Base {
  go(...args: any[]): void { }
}
const queue: any[] = [];

function foo<T extends Base>(target: BaseType<T>, ...args: Parameters<T['go']>): T;
function foo<K>(instance: K): K;
function foo<T extends Base, K>(target: BaseType<T> | K, ...args: Parameters<T['go']> | any[]): T | K {

  if (target instanceof Object && target.prototype instanceof Base) {

    const instance = new target();

    instance.go(args);
    queue.push(instance);

    return instance;

  } else {

    queue.push(target);

    return <K>target;

  }

}


class BaseChild extends Base {
  go(a: number, b: string) { }
}

foo(() => {}); // Тут все ок
foo(BaseChild, 123, 'hi'); // Тут все ок
foo(BaseChild); // Тут должна выскакивать ошибка, так как по задумке, если первый параметр Base, то тогда ожидаются далее параметры ...args: Parameters<T['go']>

Is it possible to somehow indicate in function foo<K>(instance: K): K;that the parameter instancecan contain anything, but not Baseits heirs?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Aetae, 2020-11-30
@lightalex

In typescript, structural typing. He doesn't care what class the object spawned. If the generated object structurally coincides with the signature (the signatures of all properties and methods are the same), then such an object passes by the condition:

class Foo {
  a!: number;
  b!: number;
}
function bar(arg:Foo) {};
const randomObj = {a:1, b:2, c:5};

bar(randomObj); // ok

Therefore, you cannot "exclude a certain class", as in principle you cannot limit it to a "certain class", any restrictions can only be structural.
You can forbid an object with a certain set of properties from entering, but this will restrict not only "a certain class", but also any other classes that generate an object with a similar set of fields.
A crutch is to add an empty private property to the required class and restrict it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question