Repository navigation
Conflicting definitions for Set constructor causes unexpected default generic in TS 3.5 #31990
Description
Activity
Wesley Wigham (@weswigham) I think this might be unintended fallout of your default type parameter constraints change, maybe? #30637
I think the two constructors should at least be consistent, but I'm not sure which is preferred, probably the
any-less one?I'm not sure which is preferred, probably the any-less one?
Yeah, I'm not sure why we even have a version of the constructor that defaults to
any- the's obviously quite unsafe.Arrayhas that problem too:let arr1 = new Array(10); // any[] - bad let arr2 = new Array<number>(10); // number[] - good
Daniel Rosenwasser (@DanielRosenwasser) do we want to change our behavior here? I think we last looked at it some time around #25374
Perhaps related, I notice in 3.4->3.5, SetConstructor changed from
new <T>(iterable: Iterable<T>): Set<T>;to
new <T>(iterable?: Iterable<T> | null): Set<T>;So perhaps that is changing which overload is selected when.
- addedIn DiscussionNot yet reached consensusNot yet reached consensusSuggestionAn idea for TypeScriptAn idea for TypeScript
on Jun 21, 2019 DanielRosenwasser commented
on Jun 21, 2019 MemberMore actionsYeah, it's unsafe, but it would be incredibly annoying to break people.
This sort of comes back to the "I want this to be an 'implicit any' for the
noImplicitAnyscenarios."I guess it can’t really be
unknown[]since then it wouldn’t be assignable to anything but it also can’t reasonably benever[]because then you can’t put stuff in it (unless it could be made to work like evolving array types).Just to restate, what I am concerned about here is whether "new Set()" is supposed to give you a
Set<any>or aSet<unknown>, given the conflicting definitions in the typings.I believe the intention was for 3.5 change it to
<unknown>and for that to break apps -- that is at least what 3.5 did in practice -- but I think the resolution of this bug is to make the typings express that intent more clearly.Circling back on this -- I think maybe I failed to communicate the bug here.
In practice, TS3.4 => TS3.5 changed what
new Set()gives you, fromSet<any>toSet<unknown>. (That is too late to undo, though massively annoying for us to upgrade through.)But the actual bug here is that I think you didn't change the definition of Set! It still says
anyin the typings, something else must be going wrong.Reacted by Dominic Foti Jr.
TypeScript Version: 3.4.5 vs versions after 3.5
Search Terms: set constructor setconstructor unknown
Code
Expected behavior:
In TS 3.4: we expect the default chosen param to give us a
Set<{}>.In TS 3.5: we expect a
Set<unknown>.That change was an intended change in TS 3.5.
Or, if Set has a default generic arg, I expect the same default chosen in 3.4 and 3.5.
Actual behavior:
In TS 3.4, this actually was a
Set<any>!It appears there are multiple overloads of the Set constructor.
lib.es2015.collection.d.ts says:
while lib.es2105.iterable.d.ts says:
Note that one has
T = anyand the other doesn't.So somehow TS 3.4 vs TS 3.5 decided to change whether to obey the
anydefault, I think?