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

type-container

v1.0.1

Published

Essential component for TypeScript magics.

Downloads

16

Readme

Type Container

Essential component for TypeScript magics.

npm i type-container

Fundamentals

A Type Container is simply an empty object but carries specific TypeScript type information, enabling infinite possibilities of advanced type inferences and manipulations.

The $type function produces a type container:

const $payload = $type<{ id: string }>();
// $payload -> TypeContainer<{ id: string }>

Conventionally, variables and parameters of a TypeContainer type are prefixed with $ for easy identification.

To extract the type information from a type container, use the ContainedTypeOf type:

const $payload = $type<{ id: string }>();
type Payload = ContainedTypeOf<typeof $payload>;
// Payload -> { id: string }

Practical Cases

A typical use case of type containers is to enable generic-type inference from function parameters that are not actually used within the function.

Let's say we have a createActionFactory() function:

declare function createActionFactory<
  Name extends string,
  Payload extends object
>(name: Name): ActionFactory<Name, Payload>;

interface ActionFactory<Name extends string, Payload extends object> {}

We have two generic types: Name and Payload, but only Name is referenced in the function's parameters, and thus only Name can be automatically inferred:

const factory = createActionFactory("FetchUser");
// factory -> ActionFactory<"FetchUser", object>

An ugly workaround is to get rid of type inference and explicitly specify all the generic types:

const factory = createActionFactory<"FetchUser", { id: string }>("FetchUser");
// factory -> ActionFactory<"FetchUser", { id: string; }>

However, the string literal 'FetchBook' would have to be repeated because of the lack of generic inference. When the generics are complicated, it could be impossible to manually supply all the generic, and that's when Type Containers come handy.

Let's update the function's signature to include a second parameter of type TypeContainer for only type inference purposes:

declare function createActionFactory<
  Name extends string,
  Payload extends object
>(
  name: Name,
  // 👇 TypeContainer parameter for type inference purposes only
  $payload: TypeContainer<Payload>
): ActionFactory<Name, Payload>;

Since all the generic types are involved in the parameters, the full power of TypeScript's type inference can be unleashed:

const factory = createActionFactory("FetchUser", $type<{ id: string }>());
// factory -> ActionFactory<"FetchUser", { id: string }>
// generic Name is inferred as "FetchBook"
// generic Payload is inferred as { id: string }

Library Integration

If you would like to make use of type-container in your libraries, it is recommended to list type-container as a peer dependency of your library:

{
  "peerDependencies": {
    "type-container": "..."
  },
  "devDependencies": {
    "type-container": "..."
  }
}

Alternatively, you could re-export all the members of type-container in your own library's entry file for a more invisible integration:

export * from "type-container";