2020-09-03 13:12:44 +08:00
|
|
|
import { isFunction, isUndefined } from 'lodash'
|
2020-09-02 17:44:14 +08:00
|
|
|
|
2020-09-03 13:12:44 +08:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param obj Object on which to add or modify the property.
|
|
|
|
* @param prop The property name
|
|
|
|
* @param value The value of `obj[prop]` or a getter
|
|
|
|
* @returns A restore function which can reset `obj[prop]`'s value or getter
|
|
|
|
*/
|
2021-09-04 19:29:28 +08:00
|
|
|
const defineGetter = (
|
|
|
|
obj: Record<string, any>,
|
|
|
|
prop: string,
|
|
|
|
value: any,
|
|
|
|
defaultValue?: any
|
|
|
|
) => {
|
2020-09-03 13:12:44 +08:00
|
|
|
let oldValue = defaultValue
|
|
|
|
const { get, configurable } = Object.getOwnPropertyDescriptor(obj, prop) || {}
|
|
|
|
|
|
|
|
if (isUndefined(defaultValue) && isUndefined(get)) {
|
|
|
|
try {
|
|
|
|
oldValue = obj[prop]
|
|
|
|
} catch {
|
2022-03-08 14:03:32 +08:00
|
|
|
throw new Error(
|
2021-09-17 15:27:31 +08:00
|
|
|
`TypeError: Illegal invocation. Cannot read ${prop} of '${obj}', '${obj}' might be a prototype, please specify default value instead.`
|
2021-09-04 19:29:28 +08:00
|
|
|
)
|
2020-09-03 13:12:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const oldGetter = get ?? (() => oldValue)
|
2020-09-02 17:44:14 +08:00
|
|
|
const getter = isFunction(value) ? value : () => value
|
2020-09-03 13:12:44 +08:00
|
|
|
|
|
|
|
Object.defineProperty(obj, prop, {
|
|
|
|
configurable: true,
|
|
|
|
get: getter,
|
|
|
|
})
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
Object.defineProperty(obj, prop, {
|
|
|
|
configurable,
|
|
|
|
get: oldGetter,
|
|
|
|
})
|
|
|
|
}
|
2020-09-02 17:44:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export default defineGetter
|