You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Parameters typed as unknown even when the function type has the correct types #57654
This is the behavior that starts in version 4.9, and I reviewed the FAQ for entries about function types
All the versions prior to 4.9 have both scenarios with the params typed to unknown
This is the behavior that starts in version 4.9, and I reviewed the FAQ for entries about function types
All the versions prior to 4.9 have both scenarios with the params typed to unknown
I'm pretty sure that the observed behavior change is related to #50994
(Speaking only to the reduced repro; the longer one is way too long)
These functions as written are sort of bad beyond salvaging through inference. There aren't any "good" inference sites for T so end up having observable differences between falling back to the default vs the constraint.
I guess I'd argue that unknown is the correct behavior here, since a body of these functions could call it with non-"wtf" values:
But there's really no reason to write Listener this way; it's already distributive and null and undefined will not match the infer. Writing it this way:
typeListener<T>=Textends(arg: infer U)=>unknown
? (arg: U)=>unknown
: never
causes both function's behavior to align, and correctly makes it an error to invoke f(423) in the bodies.
Barring a more realistic repro I don't have a well-justified behavior change.
I have reduced the big example as much as i could to reflect what im really using it for, i also added some more examples (one of the examples just left me speachless because i really dont understand whats going on) Here is the link
Can I get more concrete/descriptive "what I expected to happen"s than "Uhm??". I know it's obvious to you but it's a lot of work for me to reconstruct your mental state
Well, typescript reports the type of the function ready so i expected the arguments to be typed as well, but what really left me speachless and with no more ideas was the last one where the function is typed to (arg: string) => unknown yet the argument is typed as something completely different, not even unknown
It seems a problem with optional properties of objects.
You're iterating all keys in Transformers [K in keyof T], and Transformers has the optional property "ready".
When you do T[K], it find that optional property and read it as <type of that property> | undefined, and this makes the conditional type T[K] extends { handler: ... fail, because it doesn't match the "undefined" part of the type.
Adding & {} (as you did) entirely remove the "undefined" from the type, and this explains why it works.
Changing the conditional type to T[K] extends undefined | { handler: ... also works, because we're including the possibility for undefined.
Activity
Andarist commentedon Mar 5, 2024
I'm pretty sure that the observed behavior change is related to #50994
RyanCavanaugh commentedon Mar 6, 2024
(Speaking only to the reduced repro; the longer one is way too long)
These functions as written are sort of bad beyond salvaging through inference. There aren't any "good" inference sites for
Tso end up having observable differences between falling back to the default vs the constraint.I guess I'd argue that
unknownis the correct behavior here, since a body of these functions could call it with non-"wtf"values:But there's really no reason to write
Listenerthis way; it's already distributive andnullandundefinedwill not match theinfer. Writing it this way:causes both function's behavior to align, and correctly makes it an error to invoke
f(423)in the bodies.Barring a more realistic repro I don't have a well-justified behavior change.
Didas-git commentedon Mar 6, 2024
I have reduced the big example as much as i could to reflect what im really using it for, i also added some more examples (one of the examples just left me speachless because i really dont understand whats going on)
Here is the link
RyanCavanaugh commentedon Mar 6, 2024
Can I get more concrete/descriptive "what I expected to happen"s than "Uhm??". I know it's obvious to you but it's a lot of work for me to reconstruct your mental state
Didas-git commentedon Mar 6, 2024
Well, typescript reports the type of the function
readyso i expected the arguments to be typed as well, but what really left me speachless and with no more ideas was the last one where the function is typed to(arg: string) => unknownyet the argument is typed as something completely different, not evenunknownForlini91 commentedon Mar 7, 2024
It seems a problem with optional properties of objects.
You're iterating all keys in Transformers
[K in keyof T], and Transformers has the optional property "ready".When you do
T[K], it find that optional property and read it as<type of that property> | undefined, and this makes the conditional typeT[K] extends { handler: ...fail, because it doesn't match the "undefined" part of the type.Adding
& {}(as you did) entirely remove the "undefined" from the type, and this explains why it works.Changing the conditional type to
T[K] extends undefined | { handler: ...also works, because we're including the possibility for undefined.