-
-
Notifications
You must be signed in to change notification settings - Fork 5.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
[helpers TS conversion] reflection #16507
[helpers TS conversion] reflection #16507
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/56984 |
f573af9
to
3e52aa9
Compare
type Object = { | ||
__proto__?: any; | ||
} & { [key: string]: unknown }; | ||
|
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.
I re-used this bit in some places rather than extending object
since __proto__
isn't "official", should I remove the usage of __proto__
instead?
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.
That's not how to properly type object
IMHO. I'd rather stick with (as any).__proto__
than declaring a type with a name Object
.
// @ts-expect-error explicitly assign to function | ||
_getPrototypeOf = Object.setPrototypeOf | ||
? // @ts-expect-error -- intentionally omitting the argument | ||
Object.getPrototypeOf.bind(/* undefined */) |
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.
"Stole" these bits from #16505 approach
|
||
export default function _defineProperty<T extends Object>( | ||
obj: T, | ||
key: PropertyKey, |
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 saw the comment about using string | symbol
. Will fix it here
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.
defineProperty
is different since defineProperty
does allow number
to be a valid object key. Using string | symbol
is mistyping.
for (var i = 0; i < objectSymbols.length; i++) { | ||
var sym = objectSymbols[i]; | ||
var objectSymbols: Array<Symbol> = Object.getOwnPropertySymbols(descs); | ||
for (const sym of objectSymbols) { |
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.
The babel 7 helpers should be ES5-compliant, so we should stick to the good old for loop.
e97615a
to
c359ad1
Compare
this: unknown, | ||
...args: [target: T, property: P, receiver?: unknown] | ||
): P extends keyof T ? T[P] : any { | ||
let _getImpl = _get; |
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.
Let's keep the original implementation where we reassign _get
, and add a @ts-expect-error
to it.
This is different from the original one because the feature detection would run every single time _get
is called, rather than just the fist one.
Also for the other helpers.
? // @ts-expect-error -- intentionally omitting the argument | ||
Object.getPrototypeOf.bind(/* undefined */) | ||
: function _getPrototypeOf<T extends Object>(o: T) { | ||
return o.__proto__ || Object.getPrototypeOf(o); |
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.
Instead of defining Object
with __proto__
, we can use o["__proto__"]
and TS should stop complaining.
Ad an alternative, we can use
declare global {
interface Object {
__proto__: object;
}
}
and then TS will automatically let us use __proto__
on things of type object
(with the lowercase o
)
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.
Merging with interface Object
is bad. If we do this, TypeScript will add __proto__
to every object out there. Let's just use (as any).__proto__
, it is better than __proto__
goes rouge.
property: string | symbol, | ||
value: any, | ||
receiver?: any, | ||
isStrict: boolean = false, |
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.
isStrict: boolean = false, | |
isStrict?: boolean, |
This file needs to be compatible with old browsers, so let's not use default params :)
__proto__?: any; | ||
} & { [key: string]: unknown }; | ||
|
||
export default function _getPrototypeOf<T extends Object>(o: T) { |
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.
You don't need a <T>
here. Object.getPrototypeOf
doesn't require a generic.
__proto__?: any; | ||
} & { [key: string]: unknown }; | ||
|
||
export default function _objectSpread<T extends Object, U extends unknown[]>( |
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.
Normal object
just works, don't introduce Object
here.
if (desc.set) { | ||
if (desc && desc.set) { | ||
desc.set.call(receiver, value); | ||
return true; | ||
} else if (!desc.writable) { | ||
} else if (!desc || !desc.writable) { |
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.
You don't need to guard desc
here. desc
will always be defined, this is an implementation detail (about where and when set
will ever be called), just use !
.
property: string | symbol, | ||
value: any, | ||
receiver?: any, | ||
isStrict: boolean = false, |
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.
Do not use default parameters. Not only does it break the compatibility, it also increases the bundle size.
|
||
export default function _superPropBase( | ||
object: Object, | ||
property: string | symbol, |
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.
Use PropertyKey
here. You are typing arguments, not typing declared variables.
|
||
function set( | ||
target: Object, | ||
property: string | symbol, |
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.
And PropertyKey
here as well.
d1b11ec
to
80e5eb8
Compare
get: helper( | ||
"7.0.0-beta.0", | ||
'import superPropBase from"superPropBase";export default function _get(){return _get="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,r){var p=superPropBase(e,t);if(p){var n=Object.getOwnPropertyDescriptor(p,t);return n.get?n.get.call(arguments.length<3?e:r):n.value}},_get.apply(this,arguments)}', | ||
'import _superPropBase from"superPropBase";export default function _get(){return _get="undefined"!=typeof Reflect&&Reflect.get?Reflect.get.bind():function(e,t,r){var p=_superPropBase(e,t);if(p){var o=Object.getOwnPropertyDescriptor(p,t);return o&&o.get?o.get.call(arguments.length<3?e:r):o?o.value:void 0}},_get.apply(this,arguments)}', |
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.
And here too
a66b1ae
to
199472d
Compare
CI failure is not related |
defineEnumerableProperties: helper( | ||
"7.0.0-beta.0", | ||
'export default function _defineEnumerableProperties(e,r){for(var t in r){var n=r[t];n.configurable=n.enumerable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,t,n)}if(Object.getOwnPropertySymbols)for(var a=Object.getOwnPropertySymbols(r),b=0;b<a.length;b++){var i=a[b];(n=r[i]).configurable=n.enumerable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,i,n)}return e}', | ||
'import toPropertyKey from"toPropertyKey";export default function _defineEnumerableProperties(e,r){for(var t in r){var o=r[t];o.configurable=o.enumerable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,t,o)}if(Object.getOwnPropertySymbols)for(var n=Object.getOwnPropertySymbols(r),a=0;a<n.length;a++){var i=n[a];(o=r[i]).configurable=o.enumerable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,toPropertyKey(i),o)}return e}', |
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.
toPropertyKey
is unnecessary here too, similarly to objectSpread
'import superPropBase from"superPropBase";import defineProperty from"defineProperty";function set(e,r,t,o){return set="undefined"!=typeof Reflect&&Reflect.set?Reflect.set:function(e,r,t,o){var f,i=superPropBase(e,r);if(i){if((f=Object.getOwnPropertyDescriptor(i,r)).set)return f.set.call(o,t),!0;if(!f.writable)return!1}if(f=Object.getOwnPropertyDescriptor(o,r)){if(!f.writable)return!1;f.value=t,Object.defineProperty(o,r,f)}else defineProperty(o,r,t);return!0},set(e,r,t,o)}export default function _set(e,r,t,o,f){if(!set(e,r,t,o||e)&&f)throw new TypeError("failed to set property");return t}', | ||
'import defineProperty from"defineProperty";import superPropBase from"superPropBase";function set(e,r,t,o){return set="undefined"!=typeof Reflect&&Reflect.set?Reflect.set:function(e,r,t,o){var f,i=superPropBase(e,r);if(i){if((f=Object.getOwnPropertyDescriptor(i,r)).set)return f.set.call(o,t),!0;if(!f.writable)return!1}if(f=Object.getOwnPropertyDescriptor(o,r)){if(!f.writable)return!1;f.value=t,Object.defineProperty(o,r,f)}else defineProperty(o,r,t);return!0},set(e,r,t,o)}export default function _set(e,r,t,o,f){if(!set(e,r,t,o||e)&&f)throw new TypeError("failed to set property");return t}', |
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.
Maybe we should switch the order back 😂 That causes the gzip size to increase by 2 bytes.
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.
Note that it doesn't actually matter much, as imports are removed when the helpers are inlined :)
#16501 will stop considering those imports in the computed size
Thanks! |
a1edaad
to
e46b6f7
Compare
Thanks again! |
Migrate all
Reflection
helpers to TypeScript, following the specifications. This introduces changes fromyarn gulp generate-runtime-helpers