简体   繁体   中英

TypeScript: Equivalent of C#'s Generic Type Constraint for extending class?

I am attempting to write a protected abstract class which can take the subclass type as a type argument in the superclass constructor's method signature.

What I am looking for is similar to C#'s Generic Type Constraint ( where keyword) so that I can use a child type in a parameter list.

//                    where T : <base class name>
BaseAuthController<T> where T : BaseAuthController

Current superclass

export abstract class BaseAuthController {
    protected constructor(
        protected dialogRef:
            //This class shouldn't know about child classes
            MatDialogRef<Child1DialogComponent> |
            MatDialogRef<Child2DialogComponent> |
            MatDialogRef<Child3DialogComponent>
    ) {

    }
}

Current subclass

export class Child1DialogComponent extends BaseAuthController {
    constructor(dialogRef: MatDialogRef<Child1DialogComponent>) {
        super(dialogRef);
    }
}

Ideal superclass

export abstract class BaseAuthController<T> {
    protected constructor(protected dialogRef: MatDialogRef<T>) {

    }
}

References

I think you might want self-bounded generics:

export abstract class BaseAuthController<T extends BaseAuthController<T>> {
  protected constructor(protected dialogRef: MatDialogRef<T>) {}
}

This behavior is usually accomplished in TypeScript with polymorphic this types , but you can't refer to the this type in the constructor. There is an open issue about this but it doesn't look like it will be solved soon. Luckily, you can still just do it the way Java does . And your subclass should just work:

export class Child1DialogComponent extends BaseAuthController<Child1DialogComponent> {
  constructor(dialogRef: MatDialogRef<Child1DialogComponent>) {
    super(dialogRef);
  }
}

Hope that helps; good luck!

It's fundamentally different in operation, of course, but there's a way to achieve the same result:

export abstract class BaseAuthController<T extends SubClass> {
    protected constructor(protected dialogRef: MatDialogRef<T>) {

    }
}

Combining with unison types means we can specify multiple children:

export abstract class BaseAuthController<T extends SubClass1 | SubClass2> {
    protected constructor(protected dialogRef: MatDialogRef<T>) {

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM