I'm not sure how, given the following class structure and function:
class ClassA<T> {}
class ClassB<T> extends ClassA<T> {}
class ClassC<T> extends ClassA<T> {}
function doSomething<T> (classInstance: ClassA<T>) {
}
I can change the function by adding an optional argument (not breaking API) that is not accepted if the first argument is an instance of the ClassC class, but is accepted if the first argument is ClassA or ClassB instance:
class ClassA<T> {}
class ClassB<T> extends ClassA<T> {}
class ClassC<T> extends ClassA<T> {}
function doSomething<T> (classInstance: ClassA<T>, someValue?: T) {
}
doSomething<string>(new ClassA<string>); // should be allowed
doSomething<string>(new ClassA<string>, "abcd"); // should be allowed
doSomething<string>(new ClassB<string>, "abcd"); // should be allowed
doSomething<string>(new ClassB<string>); // should be allowed
doSomething<string>(new ClassC<string>); // should be allowed
doSomething<string>(new ClassC<string>, "abcd"); // should NOT be allowed
I tried tackling this with conditional types in a way similar to this:
type ValueType<T extends ClassA<any>, K> = T extends ClassC<any> ? never : K;
function doSomething<T> (
classInstance: ClassA<T>,
someValue?: ValueType<typeof classInstance, T> )
{
}
But it does not work like I expected it to and does not solve my problem. I don't think I can do this with overloading either since the ClassC extends ClassA, so the case where an instance of ClassC and a value is provided would fall under the case of ClassA and a value being provided, making it valid.
class ClassA<T> {}
class ClassB<T> extends ClassA<T> {}
class ClassC<T> extends ClassA<T> {}
function doSomething<T> (classInstance: ClassA<T>) {
}
I can change the function by adding an optional argument (not breaking API) that is not accepted if the first argument is an instance of the ClassC class, but is accepted if the first argument is ClassA or ClassB instance:
class ClassA<T> {}
class ClassB<T> extends ClassA<T> {}
class ClassC<T> extends ClassA<T> {}
function doSomething<T> (classInstance: ClassA<T>, someValue?: T) {
}
doSomething<string>(new ClassA<string>); // should be allowed
doSomething<string>(new ClassA<string>, "abcd"); // should be allowed
doSomething<string>(new ClassB<string>, "abcd"); // should be allowed
doSomething<string>(new ClassB<string>); // should be allowed
doSomething<string>(new ClassC<string>); // should be allowed
doSomething<string>(new ClassC<string>, "abcd"); // should NOT be allowed
I tried tackling this with conditional types in a way similar to this:
type ValueType<T extends ClassA<any>, K> = T extends ClassC<any> ? never : K;
function doSomething<T> (
classInstance: ClassA<T>,
someValue?: ValueType<typeof classInstance, T> )
{
}
But it does not work like I expected it to and does not solve my problem. I don't think I can do this with overloading either since the ClassC extends ClassA, so the case where an instance of ClassC and a value is provided would fall under the case of ClassA and a value being provided, making it valid.