TheSoul
TheSoul

Reputation: 5356

Typescript: creating a class as a generic extension of a generic parent

Let say I have a generic base class and a base interface:

interface IBase{
   // empty
}

class Base<T extend IBase> {
    someFunction<T>():T {
       return null;
    }
}

interface IChild extends IBase {
    child_value: string
} 


// this is generic class derived from the Base class
class Child<S extends IChild> extends Base<S> {


    // this function does not exists in base but
    // calls an inherited generic function
    doSomeThing(){

         this.someFunction({
            irrelevant: 'foo'
         })
    }
}

I don't understand why the above code compile just fine. I was thinking that when "someFunction" is called from the child object (Child), it would be restrained only to objecs of type IChild (with property "child_value"). But here it is called with the "irrelevant" promise and no complain from the compiler.

What have I missed about generics? How to derive a generic class from a generic parent and restraint the generic type to a "sub-type" of the base type?

I hope my question is clear.

Upvotes: 0

Views: 3468

Answers (1)

Fenton
Fenton

Reputation: 251062

The only thing that might be throwing you off in your example is you have two contexts for T in that base class.

Type T for the class extends IBase:

class Base<T extends IBase> {

Type T for the method has no type constraint:

someFunction<T>(): T {

If you intend the function to have the type from the class, you don't need a type parameter:

someFunction(): T {

Full Example With Corrections

Here is an annotated code example:

interface IBase{
   // empty
}

class Base<T extends IBase> { // <-- extends, not extend
    someFunction():T { // <-- we can use T from the class if that's what you intend, so no type parameter here
       return <any>null; // return <any>null; as otherwise T must be null
    }
}

interface IChild extends IBase {
    child_value: string
} 


// this is generic class derived from the Base class
class Child<S extends IChild> extends Base<S> {
    // this function does not exists in base but
    // calls an inherited generic function
    doSomeThing() {
        const x = this.someFunction();
        return x.child_value; // <-- x.child_value autocompletion and type checking

    }
}

Upvotes: 2

Related Questions