In the code snippet, the function doSomething should accept only the objects of type Base and not other types that match the type structure something like an instanceOf constraint.
interface IBase {
prop1: string;
}
abstract class Base implements IBase {
constructor() { }
prop1: string = '';
}
class Derived1 extends Base { }
class Derived2 extends Base { }
class AnotherBase {
constructor() { }
prop1: string = '';
}
// T extends Base
function doSomething<T extends Base>(obj: T) {
// do something
}
//cases should work
doSomething(new Derived1());
doSomething(new Derived2());
// cases should NOT work
doSomething({ prop1: 'test' }); // works
doSomething(new AnotherBase()); // works
How can we make the function strictly accept only objects of type Base? We can understand the present working as per the type-compatibility rules. But, is there an approach to specify a generic constraint to match exact type?
UPDATE:
From the answers to this and similar questions, It looks impossible to achieve this compile-time. I decided to include the instanceOf check to achieve the expected behaviour at runtime.
// T extends Base
function doSomething<T extends Base>(obj: T) {
if(!( obj instanceof Base)){
console.log('not a Base type');
throw new Error('An instance of Base is expected.');
}
// do something
}
//cases should work
console.log('Derived1');
doSomething(new Derived1());
console.log('Derived2');
doSomething(new Derived2());
// cases should NOT work
console.log('{..}');
doSomething({ prop1: 'test' }); // doesn't work
console.log('AnotherBase');
doSomething(new AnotherBase()); // doesn't work