lightalex
@lightalex

Как исключить определенный класс из типа в Typescript?

Есть следующий код:
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']>

Можно ли как-то обозначить в function foo<K>(instance: K): K;, что в параметре instance может быть что угодно, но только не Base и его наследники?
  • Вопрос задан
  • 72 просмотра
Решения вопроса 1
Aetae
@Aetae Куратор тега TypeScript
Тлен
В typescript структурная тпизация. Ему похрен какой класс породил объект. Если порождённый объект структурно совпадает с сигнатурой(сигнатуры всех свойств и методов совпадают), то такой объект проходит по условию:
class Foo {
  a!: number;
  b!: number;
}
function bar(arg:Foo) {};
const randomObj = {a:1, b:2, c:5};

bar(randomObj); // ok


Потому ты не можешь "исключить определенный класс", как в принципе не можешь и ограничить "определенным классом", любые ограничения могут быть лишь структурными.
Ты можешь запретить объект с определённым набором свойств на вход, но это ограничит не только "определенный класс", но и любые другие классы порождающие объект с подобным набором полей.

Костыль - добавить нужному классу пустое приватное свойство и ограничивать по нему.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы