-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(BindAll): copy over static properties from base constructor
- Loading branch information
1 parent
66af6f9
commit 489aaa4
Showing
5 changed files
with
90 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import without = require('lodash/without'); | ||
import attempt = require('lodash/attempt'); | ||
import isObject = require('lodash/isObject'); | ||
|
||
/** | ||
* Assigns all properties from an object to another object including non enumerable | ||
* properties. | ||
* @export | ||
* @template T | ||
* @template U | ||
* @param {T} to | ||
* @param {U} from | ||
* @param {string[]} [excludes=[]] | ||
* @returns {T} | ||
*/ | ||
export function assignAll<T, U>(to: T, from: U, excludes: string[] = []): T { | ||
const properties = without(Object.getOwnPropertyNames(from), ...excludes); | ||
|
||
for (const prop of properties) { | ||
attempt(assignProperty, to, from, prop); | ||
} | ||
|
||
return to; | ||
} | ||
|
||
/** | ||
* Assigns a property from one object to another while retaining descriptor properties. | ||
* @export | ||
* @template T | ||
* @template U | ||
* @param {T} to | ||
* @param {U} from | ||
* @param {string} prop | ||
*/ | ||
export function assignProperty<T, U>(to: T, from: U, prop: string): void { | ||
const descriptor = Object.getOwnPropertyDescriptor(to, prop); | ||
|
||
if (!descriptor || descriptor.configurable) { | ||
const srcDescriptor = Object.getOwnPropertyDescriptor(from, prop); | ||
|
||
if (isObject(srcDescriptor)) { | ||
Object.defineProperty(to, prop, srcDescriptor); | ||
} else { | ||
(to as any)[prop] = (from as any)[prop]; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { assignAll } from './assignAll'; | ||
|
||
const PROPERTY_EXCLUDES = [ | ||
'length', | ||
'name', | ||
'arguments', | ||
'called', | ||
'prototype' | ||
]; | ||
|
||
/** | ||
* Wraps a constructor in a wrapper function and copies all static properties | ||
* and methods to the new constructor. | ||
* @export | ||
* @param {Function} Ctor | ||
* @param {(Ctor: Function, ...args: any[]) => any} wrapper | ||
* @returns {Function} | ||
*/ | ||
export function wrapConstructor(Ctor: Function, wrapper: (Ctor: Function, ...args: any[]) => any): Function { | ||
function ConstructorWrapper(...args: any[]) { | ||
return wrapper.call(this, Ctor, ...args); | ||
} | ||
|
||
ConstructorWrapper.prototype = Ctor.prototype; | ||
|
||
return assignAll(ConstructorWrapper, Ctor, PROPERTY_EXCLUDES); | ||
} |