3

Start with a union type StringOrStuff combining two unrelated types:

class Stuff {
  constructor(readonly n: number) {}
}
type StringOrStuff = string | Stuff;

Now define an interface with a function to accept this type as a parameter.

interface Convert {
  convert(x: StringOrStuff): string;
}

Finally declare a class which, I would say 'wrongly', implements the interface:

class Converter implements Convert {
  // How can this function signature
  // be an implementation of interface Convert?
  convert(stuff: Stuff): string {
    return 'n=' + stuff.n;
  }
}

The interface proclaims that implementing methods can work with either string or Stuff, yet this implementation isn't really prepared to deal with a string. See typscript playground for a full example.

Question: Can someone explain what is going on here? Is this is a bug or a Javascript or backwards compatibility feature? Is there a rationale anywhere in the docs? Can I "fix" this by defining the interface differently?

Harald
  • 4,575
  • 5
  • 33
  • 72
  • You can use arrow function like [here](https://tsplay.dev/mLLekm) . It is unsafe to expect `convert` to accept only `Stuff` and at the same time expect `Converter` to implement `Convert` . You need to stick with one of the requirement – captain-yossarian from Ukraine Dec 15 '21 at 12:06
  • 1
    The [answer to the other question](https://stackoverflow.com/a/70277549/2887218) explains what's going on (so much so that I had to give up writing an answer here because it's nearly the same except for the particular example code). Anyway, you can definitely fix it by defining the interface using function property syntax instead of method syntax (as [here](https://tsplay.dev/w14O8W)), and the keywords to look up are "method parameter bivariance in Typescript". – jcalz Dec 15 '21 at 19:33

0 Answers0