shapeup.js
function fromShape(obj, propType, options=null) {
  const declaration = propType[SHAPE];
  if (!(declaration instanceof Declaration)) {
    throw new Error('fromShape called with a non-shape property type');
  }
  const shape = declaration.shape;
  const instance = {};
  const checker = {};
  Object.keys(shape).forEach(key => {
    const type = shape[key];
    if (type[SHAPE] instanceof Reshape) {
      // Add the reshape function to the resulting instance.
      addReshape(instance, key);
      return;
    }
    let value = obj[key];
    if (value === undefined) {
      // The object does not have the declared shape.
      // An error will be returned by PropTypes.shape.
      return;
    }
    if (type[SHAPE] instanceof Declaration) {
      // This is a nested shape type.
      instance[key] = fromShape(value, type);
      return;
    }
    if (checker.toString.call(value) === '[object Function]') {
      // This can be an unbound method: try to bind it.
      value = value.bind(obj);
    }
    instance[key] = value;
  });
  options = options || {};
  if (options.mutable) {
    return instance;
  }
  return deepFreeze(instance);
}
function fromShape(obj, propType, options=null) {
  const declaration = propType[SHAPE];
  if (!(declaration instanceof Declaration)) {
    throw new Error('fromShape called with a non-shape property type');
  }
  const shape = declaration.shape;
  const instance = {};
  const checker = {};
  Object.keys(shape).forEach(key => {
    const type = shape[key];
    if (type[SHAPE] instanceof Reshape) {
      // Add the reshape function to the resulting instance.
      addReshape(instance, key);
      return;
    }
    let value = obj[key];
    if (value === undefined) {
      // The object does not have the declared shape.
      // An error will be returned by PropTypes.shape.
      return;
    }
    if (type[SHAPE] instanceof Declaration) {
      // This is a nested shape type.
      instance[key] = fromShape(value, type);
      return;
    }
    if (checker.toString.call(value) === '[object Function]') {
      // This can be an unbound method: try to bind it.
      value = value.bind(obj);
    }
    instance[key] = value;
  });
  options = options || {};
  if (options.mutable) {
    return instance;
  }
  return deepFreeze(instance);
}
function fromShape ( obj , propType , options = null ) { const declaration = propType [ SHAPE ] ; if ( ! ( declaration instanceof Declaration ) ) { throw new Error ( 'fromShape called with a non-shape property type' ) ; } const shape = declaration . shape ; const instance = { } ; const checker = { } ; Object . keys ( shape ) . forEach ( key => { const type = shape [ key ] ; if ( type [ SHAPE ] instanceof Reshape ) { // Add the reshape function to the resulting instance. addReshape ( instance , key ) ; return ; } let value = obj [ key ] ; if ( value === undefined ) { // The object does not have the declared shape. // An error will be returned by PropTypes.shape. return ; } if ( type [ SHAPE ] instanceof Declaration ) { // This is a nested shape type. instance [ key ] = fromShape ( value , type ) ; return ; } if ( checker . toString . call ( value ) === '[object Function]' ) { // This can be an unbound method: try to bind it. value = value . bind ( obj ) ; } instance [ key ] = value ; } ) ; options = options || { } ; if ( options . mutable ) { return instance ; } return deepFreeze ( instance ) ; }
Build a property from the given object and shape property type.
The resulting property is a deeply frozen object, with initially unbound
methods bound to the provided object.
All fields in the provided object that are not declared in the shape are not
included in the returned object.
If the shape property type includes the special field "shapeup.reshape",
then a reshape method is included in that field of the returned object,
providing the ability to reshape from the object itself using a new shape
property type.

@param {Object} obj The object from which to build the shape. This object is
assumed to include all properties declared in the shape, except for the
optionally declared "shapeup.reshape" property.
@param {Function} propType The property type with the declared shape
(built using "shapeup.shape").
@param {Object} options Additional optional parameters, including:
- mutable: whether to skip deeply freezing of the resulting object.
@returns {Object} The resulting property, as a deeply frozen object.
Build a property from the given object and shape property type . The resulting property is a deeply frozen object with initially unbound methods bound to the provided object . All fields in the provided object that are not declared in the shape are not included in the returned object . If the shape property type includes the special field shapeup . reshape then a reshape method is included in that field of the returned object providing the ability to reshape from the object itself using a new shape property type .