-
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
Change the default type parameter constraints and defaults to unknown from {} #30637
Conversation
It is time - @typescript-bot test this & @typescript-bot run dt |
Heya @weswigham, I've started to run the Definitely Typed test suite on this PR at 5224a6a. You can monitor the build here. It should now contribute to this PR's status checks. |
Heya @weswigham, I've started to run the extended test suite on this PR at 5224a6a. You can monitor the build here. It should now contribute to this PR's status checks. |
unknown
from {}
unknown
from {}
At first glance, I really like most of the RWC breaks. (Once beyond all the {} -> unknown surface-level message changes.) Many of the new errors are things that point out that "hey, There's definitely a lot of baseline churn here, but this does seem to do good things. |
The DT changes are super simple to summarize:
And that seems to be it. I don't think this is actually as breaking as we thought it could be. |
…nce doesnt change surprisingly
@typescript-bot test this & @typescript-bot run dt - Between the changes to this PR and the small modifications I've made to DT, I expect this PR to be pretty clean now. We very well may be able to merge this on Monday and ship it out in a 3.5 nightly unflagged ❤️ |
Heya @weswigham, I've started to run the Definitely Typed test suite on this PR at 66049c3. You can monitor the build here. It should now contribute to this PR's status checks. |
Heya @weswigham, I've started to run the extended test suite on this PR at 66049c3. You can monitor the build here. It should now contribute to this PR's status checks. |
RWC test results now consist of:
which is exactly the kind of thing we wanted to catch here - that !!! error TS2339: Property 'toString' does not exist on type 'never'. which was issued in the !!! error TS2339: Property 'hasOwnProperty' does not exist on type 'T'. as an unconstrained type parameter cannot be treated as an object (as mentioned in the design meeting notes). Catching this was also one of our motivating examples. ❤️ !!! error TS2339: Property 'finish' does not exist on type '{}'. become !!! error TS2571: Object is of type 'unknown'.
...and that's it. All in all, all positive or neutral changes. Nice~ Now to wait for the DT results. |
I'll need to run DT again; I missed updating an old version of In any case, I have super high confidence in this change now. I'm going to take this out of draft state. ❤️ |
@typescript-bot run dt should now just have two react-dnd failures (from them using the same bad circular constraint as |
Heya @weswigham, I've started to run the Definitely Typed test suite on this PR at 66049c3. You can monitor the build here. It should now contribute to this PR's status checks. |
Ping @ahejlsberg for review so we can merge this ❤️ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one minor suggested fix, otherwise looks good.
Ahh, I just wish there was some way to declare an actual empty object |
Any reason |
@ahejlsberg |
object doesn't model an empty object as well AFAIK const a1: object = {} // (no-error) good
const b1: object = { y: 5 } // (no-error) weird, nobody says y should be there
const c1: object = [5] // (no-error) weird, I guess an array is an "object", but still...
const d1: object = 5 // (error) good, not an object The issue I have really is that I use something like this to turn props that can take an undefined value into optional props: type IsOptionalValue<C> = undefined extends C ? true: never
type DefinablePropsNames<T> = { [K in keyof T]: IsOptionalValue<T[K]> extends never ? K : never }[keyof T]
type MakeUndefinedPropsOptional<PC> = { [P in DefinablePropsNames<PC>]: PC[P] } & Partial<PC> But it seems to break when the first object generated by MakeUndefinedPropsOptional ends up being an empty object because all properties can be turned into optionals const a: MakeUndefinedPropsOptional<{}> = [] // is ok :-(
const b: MakeUndefinedPropsOptional<{ a: number | undefined }> = [] // is ok :-(
const c: MakeUndefinedPropsOptional<{ a: number }> = [] // it is not ok :D
const d: MakeUndefinedPropsOptional<{ a: number }> = {a: 5} // it is ok :D Maybe another option to fix it would be if one could modify the "?" modifier based on some extends clause, like: type MakeUndefinedPropsOptional<PC> = { [P in keyof PC](undefined extends PC[P] ? +? : -?): PC[P] } but that's not there |
Overall 👍 on this change, but I am concerned about one thing: the |
We've oft talked about wanting to try this to see how "bad" the breaks this could cause may be. Well, here's me, seeing how bad the breaks are.
Incidentally, this exposes #30634, since swapping the type parameter constraint from
{}
tounknown
makes unconstrained type parameters no longer assignable to every partial type. (Type parameters which explicitly extend{}
still will be, though.) This means I already know this PR breaksreact-redux
.Looking over the test baseline changes, most are procedural (just swapping from
{}
tounknown
) and a few of the error changes from what I can understand simply fall out from inferring from anunknown
constraint instead of a{}
(and, IMO, for the most part act in a more expected way).Take for example the
tsx
error deletion and change - they both stem from those tests not defining someJSX
namespace elements. I now default those tounknown
instead ofemptyObjectType
, which means attempts to pass properties to them no longer result in excess property errors. I think this is better (not that I think anyone should be using JSX without a well-defined JSX namespace), so I've kept it (however if there's disagreement here, this part is easy to undo separately from the type parameter default change).