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

@jrc03c/js-type-experiments

v0.0.19

Published

This is just a little utility for doing realtime type-checking in JS. Obviously, there are already [some kinds of typed arrays in JS](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Typed_arrays), but they mostly deal with number types and/o

Downloads

31

Readme

Intro

This is just a little utility for doing realtime type-checking in JS. Obviously, there are already some kinds of typed arrays in JS, but they mostly deal with number types and/or raw binary data. This utility allows for the creation of typed arrays and typed properties of any type.

Installation

npm install --save https://github.com/jrc03c/js-type-experiments

Usage

const {
  createType,
  createTypedArray,
  defineTypedProperty,
  isOfType,
} = require("@jrc03c/js-type-experiments")

const fooType = createType("Foo", v => v === "foo")
console.log("foo" instanceof fooType) // true
console.log("bar" instanceof fooType) // false

const myNumbers = createTypedArray("number")
myNumbers.push(234) // okay
myNumbers.push("Hello, world!") // error

const person = {}
defineTypedProperty(person, "name", "string")
person.name = "Alice" // okay
person.name = true // error

console.log(isOfType(234, "number")) // true
console.log(isOfType(234, "string")) // false

API

createType(name, fn)

Creates a custom type defined by a pass / fail function.

A concrete example might make the purpose of this function a little clearer. Suppose we want to create an array of non-negative integers. Using the createTypedArray function below, we could try something like this:

const x = createTypedArray("number")

But the problem, of course, is that x would accept any number, not just non-negative integers. And that's where the createType function comes to the rescue. It allows us to define a custom type without creating a whole new class (which is especially helpful for primitive values that don't use classes) merely by passing a name and a test function that tests each value to determine whether it's a member of that type or not. So, to create an array of non-negative integers, we could do something like this:

function isANonNegativeInteger(x) {
  return typeof x === "number" && x >= 0 && Math.floor(x) === x
}

const nonNegativeIntegerType = createType("NonNegInt", isANonNegativeInteger)
const x = createTypedArray(nonNegativeIntegerType)
x.push(234) // okay
x.push(-234) // error

createTypedArray(type, allowsSubclassInstances)

The type argument can be a class (like Date or a custom class) or a string representing a primitive type (like "number" or "boolean").

The allowsSubclassInstances argument is a boolean representing whether or not the array will accept subclass instances of type. It is true by default. For example, imagine that we have a class called Person that has a subclass called Employee, and that we want to create a typed array containing only Person instances. Passing true for the allowsSubclassInstances argument would imply that both Person instances and Employee instances could be inserted into the array; whereas passing false for the argument would imply that only Person (but not Employee) instances could be inserted into the array.

class Person {}
class Employee extends Person {}

const personAndSubclassesArray = createTypedArray(Person, true)
const personOnlyArray = createTypedArray(Person, false)

const alice = new Employee()
personAndSubclassesArray.push(alice) // okay
personOnlyArray.push(alice) // error

NOTE: One very important thing to know about the typed arrays created via this function is that new typed arrays of the same type cannot be created using the new keyword! For example, this will throw an error:

const NumberArray = createTypedArray("number").constructor
const x = new NumberArray() // error

The reason for this limitation is that the typed arrays created by this function are actually wrapped in Proxys — and since those can't be returned from within constructors, the constructor and the new keyword must be avoided. However, it's still possible to create new typed arrays using the static from method:

const NumberArray = createTypedArray("number").constructor
const x = NumberArray.from([2, 3, 4])
const y = NumberArray.from([5, 6, 7])
const z = NumberArray.from()

Of course, you can also use the createTypedArray function multiple times in a row to create the same kinds of typed arrays:

const x = createTypedArray("number")
const y = createTypedArray("number")
x.constructor === y.constructor // true

NOTE: Another limitation of typed arrays is that they can't be subclassed. That functionality is on my to-do list, but I haven't gotten to it yet!

defineTypedProperty(object, property, type, options)

The property argument must be a string representing the name of the property to be created.

The type argument works the same as in the createTypedArray function above.

The options argument here is actually the same as the options argument passed into Object.defineProperty (called descriptor in the MDN docs) with only one addition: it can optionally take an "allowsSubclassInstances" property that must be a boolean. That property has the same functionality as in the createTypedArray function above.

By the way, here's a useful little recipe if you need to define a property whose type is a typed array. For example, in a class called Person, there might be a property called nicknames that's supposed to be an array of (only) strings. To define such a property, do this:

const {
  createTypedArray,
  defineTypedProperty,
} = require("@jrc03c/js-type-experiments")

class Person {
  constructor() {
    // ...

    defineTypedProperty(
      this,
      "nicknames",
      createTypedArray("string").constructor,
    )

    // ...
  }
}

In other words, we create a temporary typed array using the createTypedArray function, specifying "string" as the type, and then immediately use the constructor of that array since that's the "type" of value — i.e., the StringArray type — that the property nicknames should accept.

isOfType(value, type, allowsSubclassInstances)

Returns a boolean indicating whether or not value is of type type. Optionally, allowsSubclassInstances can be set to true or false to indicate whether or not value is allowed to be a subclass of type. (This argument makes no difference for primitive types, though, since they can't be subclassed as far as I know.) For example:

isOfType(3, "number") // true
isOfType(3, "string") // false
isOfType(3, Date) // false

class Person {}
class Employee extends Person {}

const alice = new Employee()
isOfType(alice, Person) // true
isOfType(alice, Person, false) // false

NOTE: Be aware that null and undefined values will match any type! For example:

isOfType(undefined, "number") // true
isOfType(null, "string") // true

The reason for this behavior is that it's useful to be able to assign null or undefined values to (e.g.) typed arrays or typed properties such as those created with the createTypedArray and defineTypedProperty functions.

Notes

NaN, null, and undefined values: Arrays and properties of any type will accept null and undefined values without throwing errors. Number arrays and number properties will also accept NaN values.