Skip to content
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

Literal not contextually narrowed when returned from an abstract method #55318

Closed
ssalbdivad opened this issue Aug 9, 2023 · 6 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@ssalbdivad
Copy link

ssalbdivad commented Aug 9, 2023

πŸ”Ž Search Terms

symbol string number literal abstract narrow return class subclass

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried

⏯ Playground Link

https://www.typescriptlang.org/play?#code/MYewdgzgLgBGCuBbGBeGBWAsAKFJW0ATqjAEQBmIIpOe0MEAnsmgMrMBGIANgBQCUOHAEMORYcFjBuwiBBgAhWQFMYAbxwwtMUeMkwA5sqisohAJZgDAgFxlK1Tdt1mJsI1ABySDssK2MJy0XQjdDY3ZELj5+OyhGAAdlEHIGZiCdMVd9DwBhWShlABNI6ID4pJS0xBwAXyFcGTkYXIALc24imGUAD0KwIvklCFUNbG0YAHpJmABRQkIQQjsAFUTVAHIiSwMNmHN5MBBYWQhzAzBRblUoEBgKzYoqUg2Mj1MLKwF1DInCY3ghDADDMGXq2Ay0zmCyWq3WMA2CCifj2Bzgxx0cnOlw413udweCPQr3G2g83mR-n4P1JEy0-yggOBSLBDQmUPmi2WWjWSQRTCiPFRhwxp2xVxuBPhG3gYHMAEd4KoBdESRN3pweN8xnTtAymdVWRDaVMZpzYTzpSqhfsRScsRcJfj7tLZQqldVVW9jPloMVSlrqTrdaaYKxzIgOsJCNxGDBgAUdiDiEs4EhnQ8qkQYKnM6kkTB-hAkpJzAA3ZSxmBFEDKeT-RAgCv3VqqPxcgA0DAJ7XkI2UiHktxgvhgbsVkpbys13HjKl+eoBQOqmJdlVSAqN4KAA

πŸ’» Code

const num = 5
const str = "foo"
const sym = Symbol()

abstract class Base {
    abstract getString(): "foo"
    abstract getNumber(): 5
    abstract getSymbol(): typeof sym
    abstract getCastedSymbol(): typeof sym
}

class Child extends Base {
    // Error: Type 'string' is not assignable to type '"foo"'
    getString() {
        return str
    }

    // Error: Type 'number' is not assignable to type '5'
    getNumber() {
        return num
    }

    // Error:  Type 'symbol' is not assignable to type 'unique symbol'
    getSymbol() {
        return sym
    }

    // Error:  Type 'symbol' is not assignable to type 'unique symbol'
    getCastedSymbol() {
        // Similarly casting str or num to typeof str or typeof num respectively does remove the error, so this seems to be unique to the symbol case
        return sym as typeof sym
    }
}

πŸ™ Actual behavior

Return types were not contextually narrowed and allowed.

πŸ™‚ Expected behavior

Return types are contextually narrowed and allowed. Currently the best workaround is to add an explicit return annotation. Symbol case is possibly related to #53276, associated PR is #54778

@MartinJohns
Copy link
Contributor

I believe this to be a duplicate of #32082.

@ssalbdivad
Copy link
Author

@MartinJohns Interesting, it does seem related although it explicitly states:

This proposal only applies to implements, not extends

It also seems like beyond the lack of literal narrowing here, the fact that the symbol type doesn't work even when cast seems worth addressing.

@RyanCavanaugh
Copy link
Member

This is more in spirit of #23911 - the method signature (both param and return type) should ideally be modified by the extends type as well

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Aug 9, 2023
@typescript-bot
Copy link
Collaborator

This issue has been marked as "Duplicate" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Aug 12, 2023
@ssalbdivad
Copy link
Author

@RyanCavanaugh I would love to have full parameter inference when extending a class, but a lot of my confusion around this was a lack of understanding how "fresh" literal references work, because my intuition was that the function should normally be inferred as returning the const type (which I still believe it probably should, but that seems unlikely to change).

That said, the symbol case seems clearly to be distinct from the issue you mentioned- there is no question that if I explicitly cast the return type like that, it should be inferred that way like the literal types, right?

Is there an existing issue for this?

@ssalbdivad
Copy link
Author

Symbol return type widening is tracked here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants