2.2.2 • Published 3 years ago

bind-deep v2.2.2

Weekly downloads
3
License
MIT
Repository
github
Last release
3 years ago

Bind Deep

Lightweight module for binding a function or object deeply

npm version check status minified + gzip bundle size license: MIT

Description

Bind an object to this in all methods in a function, object, or array. A simple, single-dependency (only for TypeScript types) alternative to deep-bind.

Features

  • Binds the root function and all own, enumerable property functions including property accessors
  • Compatible with functions, arrays, objects, custom classes, and array-likes
  • Binds the this value and optionally, additional arguments just like func.bind()
  • Copies objects and enumerable properties deeply
  • Preserves and copies prototypes for all types
  • New in v2.1.0: Strict TypeScript type definitions

Installation

npm install bind-deep --save

Usage

bindDeep(object, thisArg, [...args])

Returns: Function | Object | Array - The function or object passed as object but with itself and all methods bound to thisArg

ParameterTypeDescription
objectFunction | Object | ArrayFunction or object to bind itself and all of its methods
thisArgObjectThe value bound to this for each bound function and method when called
...argsanyArguments provided to the bound function when the bound function is invoked

Example

// Require bind-deep
const bindDeep = require("bind-deep");


// Original object and function
// Could also be an actual object
const func = function() {
    // Use `this`
};
func.method = function() {
    // Use `this` again
};

const obj = {
    method() {
        // Use `this`
    }
};


// Deeply bound object and function
// `thisArg` will be what every function and method will see as `this`
const boundObj = bindDeep(obj, thisArg);
// => {method: [Function: bound]}

const boundFunc = bindDeep(func, thisArg);
// => {[Function: bound] method: [Function: bound]}

TypeScript

All types inferred or annotated are preserved from the original functions and objects. The type definitions are incredibly strong deep types as the only negative side-effects are:

  • If bound arguments are added, the arguments in call signatures are renamed by their bound position.
  • If more than around 39 bound arguments are added, TypeScript will error Type instantiation is excessively deep and possibly infinite.
    • If you somehow do this, slap on an as any or your manually created type

An in-depth explanation is commented inside of index.d.ts and below with example code.

// Import bind-deep
import bindDeep from "bind-deep";


interface OriginalThis {
    discriminator: string;
}

// Original function
const myFunction = function (this: OriginalThis, arg1: string, arg2: number) {
    return this;
};
myFunction.method = function (this: OriginalThis, arg1: string) {
    return this;
};
myFunction.primitive = "string";

// `thisArg` value
const newThis = { newThis: "that's me!"};

// Deeply bound functions
const boundFunction = bindDeep(myFunction, newThis);
const boundFunctionWithArgs = bindDeep(myFunction, newThis, "add arg1 for each function");

/*
    Root call signature: `(arg1: string, arg2: number) => OriginalThis`
    - `this` argument type omitted from the original call signature as it is now bound
    - All other argument types and names are preserved
    - Returns `newThis` as `OriginalThis` due to the return value inferred by TypeScript
*/
boundFunction("arg1", 10); // returns `newThis`
/*
    Root call signature when passing an argument: `((args_0: number) => OriginalThis)`
    - Similar explanation to the root call signature
    - `arg1` argument type omitted from the original call signature as it is now bound
    - `arg2` is represented as `args_0` with the number type preserved
        - This unfortunate renaming only occurs when binding arguments
*/
boundFunctionWithArgs(10); // returns `newThis`

/*
    Method call signature: `(method) method(arg1: string): OriginalThis`
*/
boundFunction.method("arg1"); // returns `newThis`
/*
    Method call signature when passing an argument: `(method) method(): OriginalThis`
*/
boundFunctionWithArgs.method(); // returns `newThis`

/*
    Primitive property type: `primitive: string`
*/
const myString: string = boundFunction.primitive; // still "string", typings preserved

License

Copyright Evelyn Hathaway, MIT License

2.2.1

3 years ago

2.2.2

3 years ago

2.2.0

3 years ago

2.1.0

4 years ago

2.0.2

5 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.0.0

6 years ago