Skip to content

Polymorphism not working correctly with union types #42032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hgl opened this issue Dec 18, 2020 · 3 comments
Closed

Polymorphism not working correctly with union types #42032

hgl opened this issue Dec 18, 2020 · 3 comments

Comments

@hgl
Copy link

hgl commented Dec 18, 2020

TypeScript Version: 4.1.2

Search Terms: polymorphism union

Code

abstract class Person {
  name: [string, string]

  constructor(p: Person)
  constructor(p: {name: string})
  constructor(p: Person | {name: string}) {
    if (p instanceof Person) {
      this.name = p.name
    } else {
      let parts = p.name.split(/\s+/)
      this.name = [parts[0] || "", parts[1] || ""]
    }
  }
}

class SadPerson extends Person {
  sadness: number
  constructor(p: {name: string}, sadness: number) {
    super(p)
    this.sadness = sadness
  }
  cry() {
    console.log("crying")
  }
}

class HappyPerson extends Person {
  happiness: number
  constructor(p: SadPerson)
  constructor(p: {name: string}, happiness: number)
  constructor(p: SadPerson | {name: string}, happiness?: number) {
    super(p)
    this.happiness = p instanceof SadPerson ? -p.sadness : happiness!
  }
  smile() {
    console.log("smiling")
  }
}

Expected behavior:
super(p) in HappyPerson's constructor should compile successfully.
Actual behavior:
ts complains "No overload matches this call."

Though it can be fixed by replacing super(p) with

if (p instanceof Person) {
  super(p)
} else {
  super(p)
}

But this feels strictly redundant.

I'm pretty sure there is already some ticket that described this, but I couldn't find it using the search term. Hope someone could link to it and I will close this one as a duplicate.

Playground Link:
https://www.typescriptlang.org/play?#code/IYIwzgLgTsDGEAJYBthjAgCgUymA9gHYIDeAUAgocALbYBcCA2pFAJaEDmANAqx5wC6ZCkiKsArvHxQAFAAdGOPEQCUo2OOhSIMhYxLU6jflwC+6ypsKTpcxVlwFiAH1JGGfaAIulRlNgAzBAUEDkhgQlhsfGDlZ1U-SmSECAALNjAAOg8EAF4EeRzabH8EMwRsZDBsJJSEZGxEeWAoCAwCoo8ssHlkNghZAHoAHTAAaiHLevTM4rp85ha2sCYABkEEFzcAIh3eZfamAEZN7YQ94RSzURubshQ0DABlYAATeKJKgA8IbEI3hhPsRyJQwO9CNh0IxCBIaCBcBotFAdHoHIYSiZvOZeOC3pDoVQ4QioIlQckwBJ5LgFNNKLNsniCR0+BCoWBbhooABPWRksrWAiNLLIfCcWQ7WA8gQ7aZ3ESPdAIAASwHk8m5wJ+fwBQKcX3JaTV8g47JhxMRVmRqPsjFeH31hGmgu0dn07kxXnYOIQRvVpsJsPhuGd1rdDntWrcGOMXp8vD9JuZAH5zcHSXUwVSafI6akMtlEwGWfIwjYIJForEEJHHQhkwgALRFJnshCMIvMgCEnLBNDYjT5mbENnwwtF4p2YH7-S4ss5ZiAA

Related Issues:

@hgl
Copy link
Author

hgl commented Dec 18, 2020

Also, having to use happiness! doesn't feel right, since it should be possible to deduce from the overloads that since p is a SadPerson, happiness can't be undefined.

Not sure if it relates to #22609, since this one is about optional parameters.

@MartinJohns
Copy link
Contributor

Your issue is completely unrelated to polymorphism, but instead to overloads. Duplicate of #40827.

@hgl
Copy link
Author

hgl commented Dec 18, 2020

Thanks. You're correct. If I replace constructor(p: SadPerson) with constructor(p: Person), ts complains with the same error.

This ultimately links to #1805, also from @MartinJohns.

@hgl hgl closed this as completed Dec 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants