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
Okay so the problem here is that Name extends keyof Test can be a union of keys - in which case name and args can be mismatched1, so TS is warning you that the call is unsafe for that reason.
You really need #27808 to deal with this properly. Short of that, youβll just have to ts-ignore the error.
TS doesn't provide any facilities to ignore this particular error that I know is irrelevant to me.
Could you elaborate? On the face of it it looks false: TS provides type assertions, the any type, and the //@ts-ignore directive, each of which could be used to prevent your code from complaining. I'm not recommending you use any of those, but I'm wondering why they don't count as "facilities to ignore" your error.
β¦which therefore makes the inner call to fn unsafe. Hence the error message.
I'm afraid I don't understand what is unsafe here. It correctly points out that you can't run one with a number.
I'd say #47109 is the current way to express this sort of thing:
I am once again finding myself at the bottom of the confidence curve. Hats off, this seems to check out.
TS doesn't provide any facilities to ignore this particular error that I know is irrelevant to me.
Could you elaborate? On the face of it it looks false: TS provides type assertions, the any type, and the //@ts-ignore directive, each of which could be used to prevent your code from complaining. I'm not recommending you use any of those, but I'm wondering why they don't count as "facilities to ignore" your error.
Which one of these can tell TS to ignore this particular error and nothing else, again? @ts-ignore ignores the whole line, so other errors can slip in. I run strict, so any any is an error in itself. I tried to assert the type of ...args, but came back empty-handed too.
Joe Calzaretta (@jcalz) Worth noting that your solution suffers from the exact same unsoundness as shown here, despite removing the error in the implementation. This pattern really does beg for oneof constraints.
I see the problem now. Strange how run('one', 123) gives an error, but run('one' as keyof Test, 123) doesn't, despite the same type being declared in the function argument. My TS knowledge is not enough to reason about what's going on at this point.
As it's my own code, this solution still seems perfectly safe for my particular use case.
In the first case, name is typed as "one"; in the second case it's typed as keyof Test. That's the difference.
By giving a union of keys for Name, you get a union of function types for Test[Name]. Then, because Parameters is distributive, it resolves to a union of those functions' parameter types. TS doesn't understand that these unions are all supposed to correlated (there's a separate issue about that, fwiw). By passing a string literal directly, it infers a string literal type for Name instead of just keyof Test, TS then knows exactly which function Test[Name] refers to, and you get your nice type checking on the call.
Joe Calzaretta (@jcalz) Worth noting that your solution suffers from the exact same unsoundness as shown here, despite removing the error in the implementation. This pattern really does beg for oneof constraints.
Activity
fatcerberus commentedon Jun 8, 2023
Okay so the problem here is that
Name extends keyof Testcan be a union of keys - in which casenameandargscan be mismatched1, so TS is warning you that the call is unsafe for that reason.You really need #27808 to deal with this properly. Short of that, youβll just have to ts-ignore the error.
Footnotes
Put more generally, it is not safe to call a union of function types with a union of their parameter types. β©
stronny commentedon Jun 8, 2023
Nevertheless it does typecheck the calls correctly, so everything works exactly as I expect it to, except the error message.
fatcerberus commentedon Jun 8, 2023
Yes, but this call also typechecks:
β¦which therefore makes the inner call to
fnunsafe. Hence the error message.jcalz commentedon Jun 8, 2023
I'd say #47109 is the current way to express this sort of thing:
Playground link to code
Could you elaborate? On the face of it it looks false: TS provides type assertions, the
anytype, and the//@ts-ignoredirective, each of which could be used to prevent your code from complaining. I'm not recommending you use any of those, but I'm wondering why they don't count as "facilities to ignore" your error.stronny commentedon Jun 8, 2023
I'm afraid I don't understand what is unsafe here. It correctly points out that you can't run one with a number.
I am once again finding myself at the bottom of the confidence curve. Hats off, this seems to check out.
Which one of these can tell TS to ignore this particular error and nothing else, again?
@ts-ignoreignores the whole line, so other errors can slip in. I run strict, so anyanyis an error in itself. I tried to assert the type of...args, but came back empty-handed too.fatcerberus commentedon Jun 8, 2023
It does not: See Playground
Joe Calzaretta (@jcalz) Worth noting that your solution suffers from the exact same unsoundness as shown here, despite removing the error in the implementation. This pattern really does beg for
oneofconstraints.stronny commentedon Jun 8, 2023
I see the problem now. Strange how
run('one', 123)gives an error, butrun('one' as keyof Test, 123)doesn't, despite the same type being declared in the function argument. My TS knowledge is not enough to reason about what's going on at this point.As it's my own code, this solution still seems perfectly safe for my particular use case.
fatcerberus commentedon Jun 8, 2023
In the first case,
nameis typed as"one"; in the second case it's typed askeyof Test. That's the difference.By giving a union of keys for
Name, you get a union of function types forTest[Name]. Then, becauseParametersis distributive, it resolves to a union of those functions' parameter types. TS doesn't understand that these unions are all supposed to correlated (there's a separate issue about that, fwiw). By passing a string literal directly, it infers a string literal type forNameinstead of justkeyof Test, TS then knows exactly which functionTest[Name]refers to, and you get your nice type checking on the call.stronny commentedon Jun 8, 2023
That actually makes sense. Thank you.
I suppose I should go ahead and close the issue now.
jcalz commentedon Jun 8, 2023
Yeah, see #48730