-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Intuitive != expected != actual behaviour when combining string and symbol keys #26470
Comments
Another small example from #26257: If const SYM = Symbol();
declare function foo(obj: {[x: string]: number}): void;
foo({a: 1, [SYM]: 'sym'}); // Compiles fine |
@RyanCavanaugh would you mind triaging this issue please? |
Thanks @RyanCavanaugh. Can we clarify what the bug is here exactly? Is it that the string index seems to include symbol keys under certain conditions, or is it that the string index doesn't include symbol keys under certain conditions? |
I'm pretty unclear on which behavior is the desired one, which is why I was procrastinating on this one. In any case the property order really shouldn't matter, though. |
I see. If it turns out that symbols must conform to string indexes, then I hope some consideration is given to how to declare things like FWIW I can't think of any scenarios where you'd want a strongly-typed symbol property to be constrained by the string index. Symbol-keyed properties usually serve a very specific purpose (think of all the well-known symbols). The type of a symbol-keyed property is usually unrelated to the types of other keys in the same object. Certainly unrelated to string keys, and usually to other symbol-keyed properties too. |
Hey @weswigham, may I ask if there is something holding up the fix for this? Your PR has sat there for a couple of months now. Just wanting to know if this will be addressed by the time v3.2 comes out. |
3.2 is a no at this point, given it's size, I'd guess. I'm still pushing for it, though. It's just hard to convince the relevant parties that it is both the correct fix (easy) and worth the change (hard). This issue and the others linked in the fix don't make the best case for a change of that size (not many upvotes, little obvious impact), so it's slow going. |
OK. Well the PR has a much broader scope of changes that what this issue raises. Would a more limited change have more chance of making progress - eg just stop string indexes from constraining symbol keys? The other changes could possibly be approached later if there is demand. |
So that's not really the issue here. The issue is that mapped types have a concept of mapping |
I see (and thanks for explaining why this issue manifests order-dependence!). Your PR has quite a few upvotes. If it fixes known issues (like this one) and otherwise has little obvious impact, I guess there must be some other reason why the PR is facing resistance? Does it break anything or slow down the compiler or preclude other future features under consideration? Usually issues go unresolved because nobody has had time to create the PR, but in this case you have already done the work. So just curious why it can't be merged. |
Just complexity. Index signatures are currently represented trivially internally, while my change fleshes them out a bit more and makes them more generic. |
You wouldn't need them to fix this issue though, right? I thought the problem here is not the lack of symbol index info. Rather, it's that the current string index behaviour is so broad that it affects unrelated symbol properties. |
Note a closely related issue to this was fixed earlier this year - #21217. That PR states:
In that light, is this issue actually a regression? I still think this one can be resolved by just modifying string indexer behaviour without adding any other indexer types. |
Also @weswigham you mention this is a problem with mapped types, but the currently behaviour manifests with no mapped types anywhere, eg tsc acts the same if we change declare function foo<TArg, TRet, TDir>(options:
{[x: string]: (arg: TArg) => TRet} // NB string indexer, not mapped type
& {[directive]?: TDir}
): void; I don't know if the compiler treats that as a mapped type internally, but at least on the surface it appears to be an issue with string index signatures. |
What's the status on this? Is there anything holding it up right now? |
TypeScript Version: 3.1.0-dev.20180813
Search Terms: string index inference, string key inference
Code
Intuitive expected behaviour:
All three cases compile without errors, with the string and symbol keys typed separately, since the type declaration clearly distinguishes the string keys from the symbol one.
Expected behavior according to #26257 (comment):
That comment suggests that all three cases should fail to compile, since the string index signature covers all symbol keys too, so any symbol key would have to conform to the string index signature, and they don't conform in any of the three cases in the code above.
Actual behavior:
Case 1 fails to compile, but Case 2 and 3 compile fine and in fact do type the string and symbol keys separately as intended by
foo
's definition.Playground Link: here
Related Issues:
Taken directly from #26257 (comment). But the issue containing that comment is marked as 'working as intended' so I thought it would be better to open a new issue for this specific case.
The text was updated successfully, but these errors were encountered: