Add nullability annotations to core.d.ts and es6.d.ts#7650
Add nullability annotations to core.d.ts and es6.d.ts#7650mhegazy merged 3 commits intomicrosoft:masterfrom Arnavion:lib-d-ts-fixes
Conversation
src/lib/es6.d.ts
Outdated
| * @param source The source object from which to copy properties. | ||
| */ | ||
| assign<T, U>(target: T, source: U): T & U; | ||
| assign<T, U>(target: T, source: U | null | undefined): T & U; |
There was a problem hiding this comment.
This (and similar for the overloads below) is needed because null and undefined are allowed and ignored by Object.assign, but the compiler should not infer U as null if null is passed in, as the result T & null is meaningless.
Should I add a comment to that effect?
There was a problem hiding this comment.
Actually, on closer look it seems U is still specialized as null instead of {}. But also the resulting type T & null doesn't seem to have any issues either.
Should I remove the | null | undefined from this function?
There was a problem hiding this comment.
T & null and T & undefined should not be a problem, because null and undefined add no new member to the type? In fact, I think the type system could (should?) simplify T & null & undefined to just T.
If it were T | null that would be a real problem.
There was a problem hiding this comment.
BTW I don't think Object.assign is "meant" to explicitely accept undefined. It reflects the fact the the parameter is optional and that should probably be modelled with assign<T>(target: T): T, so that you can call assign(x); or maybe assign<T, U>(target: T, source?: U).
Note that removing null and undefined from being explicit in the signature doesn't change the fact that assign(x, null) is still valid.
Of course the right thing to do here would be variadics (2.1) since the real signature is assign<T, ...U>(target: T, ...source: ...U): T & ...U.
There was a problem hiding this comment.
T & nullandT & undefinedshould not be a problem, becausenullandundefinedadd no new member to the type?
Yes, it appears so, but...
In fact, I think the type system could (should?) simplify
T & null & undefinedto justT.
It doesn't, hence my initial concern that this would be problematic. But it seems to be fine regardless, in that the instances of T & null appear to be usable as T everywhere. I'm waiting for the TS team to confirm / deny if this is expected behavior or a bug.
BTW I don't think
Object.assignis "meant" to explicitely acceptundefined.
Yes, this is what I thought as well. I'm not familiar with all of assign's uses, so if it's not expected that users will want to use it with null / undefined sources then it would be nice to have a way to specify that U can't be null. Perhaps U extends {} ? I'm not in front of tsc to try at the moment.
There was a problem hiding this comment.
Since this is brand new stuff, maybe @ahejlsberg should add a reduction rule from T | null | undefined to T... that may simplify a few other places where this might come up?
There was a problem hiding this comment.
do not think this is the correct change here. the current signature declaration is better. i think what you want is a type operator like the expression operator ! (which does not exist) on the return type to indicate that null and undefined are ignored. e.g. assign<T, U>(target: T, source: U): T! & U!;
| * predicate. If it is not provided, undefined is used instead. | ||
| */ | ||
| findIndex(predicate: (value: number) => boolean, thisArg?: any): number; | ||
| findIndex(predicate: (value: number) => boolean, thisArg?: any): number | undefined; |
There was a problem hiding this comment.
predicate is incorrect, it should be the same as for find().
See https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/TypedArray/findIndex
There was a problem hiding this comment.
@Arnavion feel free to send a separate PR for the predicate changes.
There was a problem hiding this comment.
@mhegazy And should I move the other commits after the first one into a separate PR as well?
There was a problem hiding this comment.
On a second thought, the commit messages look clear enough, so feel free to include the findIndex chances in this PR if you like or have it in a separate one. up to you.
There was a problem hiding this comment.
I've removed them from this PR. Will make another one.
|
thanks! |
|
The other changes are in #7664 |
|
|
||
| // Non-standard extensions | ||
| compile(): RegExp; | ||
| compile(): this; |
There was a problem hiding this comment.
I don't think there is a guarantee that compile returns your subclass if you subclass RegExp, so it should return plain RegExp instead.
There was a problem hiding this comment.
According to ES specs it should return the this value of the compile() call.
So using this type here seems like the correct thing to do.
BTW: this method is deprecated so hopefully it won't matter much.
| nulland| undefinedwhere appropriate.| undefined. I have added it to the ES6 collection accessors likeMap.gethowever. I think that's better.| nullor| undefinedto functions that stringify their parameter and thus acceptnullandundefined, egSymbol(null)is the same asSymbol("null"). It doesn't seem right to allownulljust for that.1. ES6's String.normalize'sformparameter was typed as string - changed to union of string literals.1. Map and Set methods that are specced to returnthiswere not annotated as: this, changed accordingly.I can split the changes into separate PRs if you want. I just fixed them as I came across them while doing the first one.The other changes became too big and will be in another PR.
jake runtestspasses.