-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Default parameter narrowed to be defined when using void | undefined | SomeType
to type the function parameter
#48664
Comments
That is precisely what An exmaple: function doSomething(): { a: number } {
return { a: 123 };
}
function callMeMaybe(callback: () => void) {
return callback();
}
function fnWithVoidParam(param: void | { a: true }) {
if (param) {
// You'd expect boolean, but is actually number.
console.log(typeof param.a);
}
}
fnWithVoidParam(callMeMaybe(doSomething)); Granted, the behaviour of TypeScript is weird here. It actually does narrow the type, when it shouldn't. There are many issues about the behaviour of void, like #42709. You should use |
I know that |
We'd really, really, really like to just ban using For this particular scenario, have you considered using a conditional type + a parameter tuple type? |
We considered the following (simplified a little) export type Action<Element = HTMLElement, Parameter = any> =
void extends Parameter
? <Node extends Element>(node: Node) => void
: undefined extends Parameter
? <Node extends Element>(node: Node, parameter?: Parameter) => void
: <Node extends Element>(node: Node, parameter: Parameter) => void; but I just noticed that this won't work as expect when strict null checks is not turned on because Sorry if this type inconsistency issue becomes a support ticket 😅 |
This issue has been marked as 'Not a Defect' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
When typing a function parameter so that it's optional by typing it as
void | SomeType
method and defining a default parameter, the type is not narrowed toSomeType
and instead stays asvoid | SomeType
. TS can be tricked into doing so by writingvoid | undefined | SomeType
, but this feels inconsistent.From what I've read,
void
means "I promise I won't use this return value" in the context offnThatAccecptsVoidFn
in the code snippet below, so the return value can actually be anything, which means a default parameter infnWithDefaultParam1/2
maybe cannot be used to narrow the function parameter toSomeType
.This is either ok because wo broke our promise of not using the return value of the function in
fnThatAccecptsVoidFn
- in this casevoid | SomeType
with a default value should also be narrowed toSomeType
. Or TS plays it safe and says "if void is accepted, anything could be passed in" and not narrowvoid | undefined | SomeType
toSomeType
.Before you say "you could just make this an optional function parameter using
?
": This is the minimum reproducible, the actual code is in the context of sveltejs/svelte#7442 where we try to type out a function interface that makes it possible to either set a parameter as required, optional, or missing, where I found this (in my mind) inconsistency. This is related to #12400.🔎 Search Terms
function default parameter void undefined
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play?#code/MYewdgzgLgBAZmA6gSygCxAVygEQKZwCGmANlAAqEBOhAtjALwwAUADtXQFwwBuIyAExgAfGAG9C3KFUx4AvgEpGAPnEAoGJpjsatAHSEA3DAD0J+IWQkIAGhh4AHqzzAoeAWrlq1oSLAQo6PhEpBQctACMjCw6XLz8QqISUjLy0WIwkjDSsjCKKupa2uEGxmYWVrYwmGCOzq7uAPye3r7Q8EioaMHEZJS6AEzRbOHcfIIi1WACBMi1ieJZOWlMGUupeUoMqmIaWrH6RqbmAO4gVADWVXUubgLNXj7g7QgAKmiEUACCwMAurFAIAA1BIAMTAwwQ3GYW1U4wEsMKWgCXR6oX6dAGzAQMIUZXMVDwUEwVAhBxgwEIEIARngYNA0PZrHT0FTxJkUrk5DBzlMZnA5u4Wmo3h9vr9-oCQYJwcwYQVlni1EA
💻 Code
🙁 Actual behavior
void | SomeType
+ a default parameter don't narrow it toSomeType
, butvoid | undefined | SomeType
do, which feels inconsistent. See first section for more details.🙂 Expected behavior
Honestly I don't know, see sections above.
The text was updated successfully, but these errors were encountered: