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

Type 'string' is not assignable to type 'Exclude<T, number>' when narrowing using generic #54175

Closed
xsjcTony opened this issue May 8, 2023 · 3 comments

Comments

@xsjcTony
Copy link

xsjcTony commented May 8, 2023

Bug Report

🔎 Search Terms

  • remove a type from generic union as return type
  • remove a type from generic union
  • remove a certain type from generic

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about <Can't find anything related>

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.1.0-dev.20230507#code/GYVwdgxgLglg9mABGEBbARgUwE4BU4DKU2MYA5gDy4B8AFAG4CGANiJgFyK4CUnAogA8IrACaYqAGmRos2aogDeAWABQidYmyYoIbEigBPAA6Y4wRE1aZEAXjuIA5Cgw4HiAPyIABgBIFltgBfL0ROAMwAblVA1VUAejjEEABnRjJMVVBIWAREZMxmTGhcTAEoWihSqE5k4lIyRAAfRAAlTDJBI25FVQ1EBMQoOBE4aNiVLOh4JEYwOCgACxwAMTBaRmwyTmdZJry68j22joEunrUNAcWYZMQbxEZoEBZmA0QAdzhsAGt6qXQQFA8nBUJgFnB3ogADKkawAJjut1qMGYzE0jBu9UGS0QOGwX16Gi0Oj0eQKRSgJTKtB2OHwRBI5HWm243CiKhiKnGkxySFpeEIBzIcKodHCnB4EtxZUwYBEt35Hm8flwwVCXHOfWJun0xlM5nCtnsThkriVvn8LCCITCVsiYy5E3AU1y-PpQoAzKKGHaJbwNVVZfLpC5sEraoyGlLlBd1NrSYYTGYLHajTZHPy3J4LeE1barOzOUA

💻 Code

function numberToString<T>(value: T): Exclude<T, number> {
    return typeof value === 'number' ? `${value}` : value;
//  ^^^^^^ Error
}

// usage
function selectText(text: string | RegExp) {
    // todo
}

function anotherFn(arg: number | string | RegExp) {
    // this is actually working, but somehow Line 2 is still raising the error
    return selectText(numberToString(arg));
}

🙁 Actual behavior

Type 'string | T' is not assignable to type 'Exclude<T, number>'.
  Type 'string' is not assignable to type 'Exclude<T, number>'

🙂 Expected behavior

There should be no issue, since T is extending any by default, hence string should absolutely be included in Exclude<T, number>, where it should be any type but without number

@jcalz
Copy link
Contributor

jcalz commented May 8, 2023

This would probably be a duplicate of #33912 if the return type were changed to T extends number ? `${T}` : T to correspond to what the function is actually doing.

Currently if you call numberToString(10), then T is inferred as 10, making the return type Exclude<10, number> which is never. But the function implementation returns a string, which (like all values) is not assignable to never. So the compiler error is a good one.

@MartinJohns
Copy link
Contributor

but unfortunately it's not working.

It's not working because #33912 is not implemented.

where it should be any type but without number

TypeScripts type system can't represent such types. Exclude<> is only used to remove types from a union type. This would require #4196.

@xsjcTony xsjcTony closed this as not planned Won't fix, can't repro, duplicate, stale May 8, 2023
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

3 participants