npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

extension-methods

v1.0.1

Published

This library allows you to create extension methods for a given object the fatest way

Downloads

8,211

Readme

Actions Status Actions Status Actions Status Test Coverage Maintainability npm version

extension-methods

With this library, you can create 'proxy references' for your objects and access many methods that actually doesn't exists in them! This is pretty useful in the following scenarios:

  • where you need to create a method that returns an object with a lot of methods, but the code that'll use that result will only access a few of them;
  • When you have a base class and you want to implement functionalities in it without changing the original contract;

Depending on the number of methods you'll proxy through extension-methods, you can achieve a 99% faster operation than a simple new Class()

How to use it

First, you need to obtain your extension object, like this:

import { getExtender } from 'extension-methods';

export interface MyObjectExtended {
  concatFoo(): MyObjectExtended;
  concatBar(): MyObjectExtended;
}

export interface MyObject {
  value: string;
}

export const myObjectExtension = getExtender({
    concatFoo(this: MyObject) {
      return extend({ value: `${this.value}_foo` }, myObjectExtension);
    }
    concatBar(this: MyObject) {
      return extend({ value: `${this.value}_bar` }, myObjectExtension);
    }
  }
);

Now, take a look in the extend function called in the above code: this is the one who applies the extension! The first parameter must be the definition of this, as it will be a reference to the object being extended, so, you can access it and do whatever you want! So, when you need to extend methods in some object, just do it like this:

import { extend } from 'extension-methods';
import { myObjectExtension, MyObject, MyObjectExtended } from './my-object-extension';
...
...
const extended: MyObjectExtended = extend({ value: 'my string' }, myObjectExtension);

console.log(extended.concatFoo().value);
console.log(extended.concatBar().value);
console.log(extended.concatFoo().concatBar().value);
// Result:
// my string_foo
// my string_bar
// my string_foo_bar

Look that does methods actually are not present in the extended const (or in the original object), but extension-methods make it be accessible at runtime, making the call to extend being much faster! Also, in the Extender implementation, the return of concatFoo and concatBar also applies the extend function to the result, which creates a fluent interface for this use, resulting in the chained  call as you can see above! All of that, with less overload possible!

Extending Classes

You can also create extended version of Classes that will create instances of such classes with the exactly same benefits of an extended object. To achieve this, just use the method extendClass:

import * as examplePackage from './example-class';
import { extendClass, getExtender } from 'extension-methods';

declare module './example-class.spec' {
  interface ExampleClass {
    method1(): number;
  }
}

const extender = getExtender({
  method1(this: ExampleClass) {
    return this.someProperty * 3;
  },
});

export const ExtendedClass = extendClass(ExampleClass, extender);

Notice that an interface with the same name of the class is declared in the same module from where the class is imported. Doing this will make the new methods visible anywhere this code is imported.

Now, import your ExtendedClass where you want to use it!

import { ExtendedClass } './extended-class';


const test = new ExtendedClass();

console.log(test.method1());

And that's it, it'll just work!

Important

  • If some method exists in the original object and also is declared in the Extender, the original method will be used;
  • extension-methods can't be used with primitive values like stringnumber and boolean;
  • extend will naturally returns a type that is a join between the real object and the extension methods declared, but it is recommendable, if you want a cleaner type or to return such value as a result of a function, to create an interface that represent it, as you can see in the examples above;