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

overarg

v1.0.2

Published

A tool to help with returning typed arguments from overloaded functions in TypeScript.

Downloads

5

Readme

overarg

A tool to help with returning typed arguments from overloaded functions in TypeScript.

What it does

Consider an overloaded method that can take 0-3 arguments in any combination that looks like this...

public test(name: string): void;
public test(age: number): void;
public test(dob: Date): void;
public test(name: string, age: number): void;
public test(name: string, dob: Date): void;
public test(age: number, dob: Date): void;
public test(name: string, age: number, dob: Date): void;
public test(): void { }

You might have to write a bunch of logic to figure out what parameters you have, or you could do this inside the function:

const name = overarg<string>("string", ...arguments);
const age = overarg<number>("number", ...arguments);
const dob = overarg<Date>("object", ...arguments);

Each variables will be strong-typed or undefined, easy as can be. You can even have multiple arguments of the same type and specify an offset so for instance:

// 1st string provided is firstName
const firstName = overarg<string>(0, "string", ...arguments);
// 2nd string provided is lastName
const lastName = overarg<string>(1, "string", ...arguments);

Installation

npm install --save overarg

Usage

As shown in the example above, define all your overloads, but the actual function signature doesn't need any arguments.

// include in your project
import { overarg, overargFunc } from "overarg";

// offset defaults to 0, so the first match for the identifier will be used
const variable1 = overarg<type>(identifier, ...arguments);

// specify the offset as a number (indexed from 0) to get later matches (ex. offset = 1, gets the second match)
const variable2 = overarg<type>(offset, identifier, ...arguments);

type is the return desired return type, ex. string or RegExp, but the actual return overarg() will be that type | undefined (in case it couldn't match). This also allows you to set default values easily:

// sets variable1 to the value of the first argument that was a number or 100 if there wasn't one
const variable1 = overarg<number>("number", ...arguments) || 100;

Identifiers

The identifiers in this list are tested in this order:

  • "array" - Will match an argument if it is an Array.

  • "object", "boolean", "function", "number", "string", "symbol", "undefined" - Will match an argument if typeof returns the specified primitive JavaScript type.

  • string - Will match an argument that has the specified name in its prototype chain. For example, when MyClass extends MyParent, you can specify "MyClass" or "MyParent" as the identifier.

  • object - Will match an argument that is an instanceof the specified object. For example, /myRegExp/g is an instanceof RegExp.

It is important to understand what typeof and instanceof do, and how they are resolved by JavaScript, some odd examples:

typeof new Date(); // is object
typeof null;       // is object
typeof undefined;  // is undefined

Functions

When the above identifiers are not enough, you can use a Function to find the argument, by using overargFunc():

const variable1 = overargFunc<type>((arg: any): boolean => {}, ...arguments);

An example:

// test case showing monkey is not matched, but dog is
interface animal {}
interface monkey extends animal {
    type: "monkey"
}
interface dog extends animal {
    type: "dog"
}
const test = (...args: any[]): animal | undefined => {
    return overargFunc<animal>(arg => arg.type === "dog", ...args);
}
const monkey: monkey = { type: "monkey"};
const result1 = test(monkey);
assert.strictEqual(result1, undefined);
const dog: dog = { type: "dog"};
const result2 = test(dog);
assert.strictEqual(result2, dog);

Arrow Functions

Please note that JavaScript Arrow Functions do not have their own arguments https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions, but you can use ...args: any[] in TypeScript even on an Arrow Function and it will generate proper JavaScript.

In that case, you should pass ...args instead of ...arguments.

const test = (...args: any[]): void => {
    const variable1 = overarg<string>("string", ...args);
}
test("testing");

Real-World Example

// list the blobs via a streaming pattern
public list<Out = azs.BlobService.BlobResult>(): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(prefix: string): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(transform: StreamTransform<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(options: StreamOptions<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(prefix: string, options: StreamOptions<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(prefix: string, transform: StreamTransform<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(transform: StreamTransform<azs.BlobService.BlobResult, Out>, options: StreamOptions<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(prefix: string, transform: StreamTransform<azs.BlobService.BlobResult, Out>, options: StreamOptions<azs.BlobService.BlobResult, Out>): ReadableStream<azs.BlobService.BlobResult, Out>;
public list<Out = azs.BlobService.BlobResult>(): ReadableStream<azs.BlobService.BlobResult, Out> {

    // get arguments
    let prefix: string | undefined = undefined;
    let out_options: StreamOptions<azs.BlobService.BlobResult, T> = {};
    if (arguments[0] && typeof arguments[0] === "object") out_options = arguments[0];
    if (arguments[1] && typeof arguments[1] === "object") out_options = arguments[1];
    if (arguments[2] && typeof arguments[2] === "object") out_options = arguments[2];
    if (arguments[0] && typeof arguments[0] === "string") prefix = arguments[0];
    if (arguments[0] && typeof arguments[0] === "function") out_options.transform = arguments[0];
    if (arguments[1] && typeof arguments[1] === "function") out_options.transform = arguments[1];

}

This module addresses the "get arguments" section, making it look like this:

    // get arguments
    const prefix = overarg<string>("string", ...arguments);
    const transform = overarg<StreamTransform<azs.BlobService.BlobResult, Out>>("function", ...arguments);
    const options = overarg<StreamOptions<azs.BlobService.BlobResult, Out>>("object", ...arguments) || {};
    if (transform) options.transform = transform;