Skip to main content
Home

Built and signed on GitHub Actions

Works with
This package works with Node.js, Deno, BunIt is unknown whether this package works with Cloudflare Workers, Browsers
It is unknown whether this package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
This package works with Bun
It is unknown whether this package works with Browsers
JSR Score94%
Published11 months ago (0.1.1)

This package provides type-guarded versions of the has method for built-in types like `Map`, `FormData`, and `URLSearchParams` so that you can narrow `.get(key)` return type within the conditional type guard blocks.

ts-has-guards

This package provides type-guarded versions of the has method for built-in types like Map, FormData, and URLSearchParams so that you can narrow .get(key) return type within the conditional type guard blocks.

Warning

This package is pretty experimental, but I welcome improvements to the DX.

Why use this package?

If you've ever tried to call get(key) after calling has(key) and lamented the fact it still returns | undefined or | null, you know this problem well.

For example, this will throw an error in vanilla TS:

const map = new Map([["key", 1]] as const);

if (map.has("key")) {
  const value: number = map.get("key");
  //  !!!   ^---- ERROR!
}

But with this library, the type guard works like you might expect. map.get('key') will be narrowed to number instead of number | undefined.

This library provides type-guarded has methods for:

  • Map.has using GuardedMap
  • FormData.has using GuardedFormData
  • URLSearchParams.has using GuardedURLSearchParams

Getting Started

Choose your poison:

deno add jsr:@kamranayub/ts-has-guards

npx jsr add @kamranayub/ts-has-guards
yarn dlx jsr add @kamranayub/ts-has-guards
pnpm dlx jsr add @kamranayub/ts-has-guards
bunx jsr add @kamranayub/ts-has-guards

This library was built with Deno.

Usage

To use the typed versions of Map, URLSearchParams and FormData, you need to explicitly use and import them (each of them are prefixed with Guarded):

import {
  GuardedFormData,
  GuardedMap,
  GuardedURLSearchParams,
} from "@kamranayub/ts-has-guards";

// Use like regular API but you can pass an explicit set of known keys
type KnownKeys = "key1" | "key2";

const map = new GuardedMap<KnownKeys, number>();
const searchParams = new GuardedURLSearchParams<KnownKeys>();
const formData = new GuardedFormData<KnownKeys>();

When converting built-in lib types to the guarded versions, you must cast as unknown first:

map as unknown as GuardedMap<MyKeys, string>;
formData as unknown as GuardedFormData<MyKeys>;
searchParams as unknown as TypedSearchParams<MyKeys>;

You can reference the tests or docs for some more examples.

Docs

View the docs on JSR.

Shameless Plug

Maybe have a listen to typescript.fm. :microphone:

FAQ

Why can't I augment the global types?

You could with Map, however this is not supported for a published JSR package due to slow typings. If you'd like to use a local version in your app, you can copy from the StackOverflow answer and put it under a globals.d.ts file or declare global { } if using modules.

This will not work with the FormData and URLSearchParams though because those types are not generic and TS will yell at you if you try to redeclare them with generic typings.

Credits

Built on the shoulders of giants.

Inspired by @dbushell.

Built and signed on
GitHub Actions

Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";
or

Import directly with a jsr specifier

import * as ts_has_guards from "jsr:@kamranayub/ts-has-guards";

Add Package

pnpm i jsr:@kamranayub/ts-has-guards
or (using pnpm 10.8 or older)
pnpm dlx jsr add @kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";

Add Package

yarn add jsr:@kamranayub/ts-has-guards
or (using Yarn 4.8 or older)
yarn dlx jsr add @kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";

Add Package

vlt install jsr:@kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";

Add Package

npx jsr add @kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";

Add Package

bunx jsr add @kamranayub/ts-has-guards

Import symbol

import * as ts_has_guards from "@kamranayub/ts-has-guards";