-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Function arg type inference (incorrectly) unions with null but excludes others #49850
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
Comments
A workaround could be using the type of type guard function as generic: function matchLoose<T extends Function>(test: T, ...options: T extends (x: unknown) => x is infer R ? Array<R> : never) {
return options.find((o) => test(o));
}
function isStr(x: unknown): x is string {
return typeof x === 'string';
}
matchLoose(isStr, 123, 'a'); // Error as expected
matchLoose(isStr, null, 'a'); // Error as expected |
Seems like a duplicate of #14829. You don't want the TypeScript has some heuristics for accepting/rejecting/combining inference candidates; Workarounds here usually involve lowering the priority of the |
Thanks @jcalz, good tips! |
For other who arrive here, I found this to be an excellent solution: function match<T, U extends T>(test: T, ...options: Array<U | undefined>): T | undefined; |
This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
🔎 Search Terms
function arg generic inconsistent type inference
infer func arguments breaks on null
🕗 Version & Regression Information
This is the behavior in every version I tried, and I reviewed the FAQ for entries about functions and generics
⏯ Playground Link
Playground link with relevant code
Discord thread, no solutions
💻 Code
🙁 Actual behavior
matchLoose(isStr, 123)
correctly excludesnumber
, butmatchLoose(isStr, null)
incorrectly becomesmatchLoose<string | null>
.🙂 Expected behavior
I expect
matchLoose(isStr, null)
andmatchLoose(isStr, 123)
to both throw errors, becauseisStr
narrows<T>
strictly. (I expect the intersection to work regardless of argument order too.)The text was updated successfully, but these errors were encountered: