0

I have a super class, such as

class SuperClassy {
}

Which has many other classes extending it:

class SubClassy extends SuperClassy {
}

class OtherSubClass extends SuperClassy {
}

etc.

I have functions for which I want to specify the argument must be in this group of derived classes.

I don't want to have to create a union type manually, I'd rather just declare that the argument in question must inherit from SuperClassy.

Something like:

function doStuff(c: InheritsFrom<SuperClassy>) {
}

such that this will compile:

doStuff(new SubClassy()) {
}

and this will not:

doStuff(4);

-- EDIT --

Here is an example where simply requiring parameter to be SuperClassy does not work:


class SuperClassy {
  id: string;
}

class SubClassy extends SuperClassy {
  x: number;
}

class OtherSubClass extends SuperClassy {
  y: number;
}

function doStuff(c: (c: SuperClassy) => (d: SuperClassy) => boolean) {
  return 'j';
}

doStuff((c: SubClassy) => {
  return (k: OtherSubClass) => {
    return c.id === k.id;
  }
});

Compiler throws this error:

Argument of type '(c: SubClassy) => (k: OtherSubClass) => boolean' is not assignable to parameter of type '(c: SuperClassy) => (d: SuperClassy) => boolean'.
  Types of parameters 'c' and 'c' are incompatible.
    Property 'x' is missing in type 'SuperClassy' but required in type 'SubClassy'.
3
  • 2
    Can't you just do function doStuff(c: SuperClassy) ? Commented Jul 28, 2021 at 4:05
  • See updated question for use case where that breaks Commented Jul 28, 2021 at 4:56
  • 1
    Function type is more complex than you thought. They are contravariant in their argument types and covariant in their return type. You need to rethink about them. Basically, the function you passed in to doStuff is not a subtype of the parameter type defined for doStuff. i.e. (c: SubClassy) => ... is not a subtype of (c: SuperClassy) => ... it's actually the opposite. Commented Jul 28, 2021 at 5:09

1 Answer 1

1

How about using generics? (I added default values to the class definitions to suppress compiler errors.

class SuperClassy {
  id: string = "id";
}

class SubClassy extends SuperClassy {
  x: number = 0;
}

class OtherSubClass extends SuperClassy {
  y: number = 0;
}

function doStuff<T extends SuperClassy, U extends SuperClassy>(
  c: (c: T) => (d: U) => boolean
) {
  return "j";
}

doStuff((c: SubClassy) => {
  return (k: OtherSubClass) => {
    return c.id === k.id;
  };
});

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.