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

types-spring

v2.2.2

Published

a package that provides more accurate and powerful typescript capabilities

Downloads

188

Readme

types-spring

npm npm

A package that aims to eliminate some of the shortcomings of the built-in types in standard ts libraries and deliver additional utility types that will facilitate daily work. Inspired by ts-reset.

Built-in types features:

Array.map

before:

const a = [1, 2, 3] as const;
let arr = a.map(r => r + '')                              // string[]

after:

const a = [1, 2, 3] as const;
let arr = a.map(r => r + '')                             // [string, string, string]

Array.isArray

before:

function checkArray(a: { a: 1 } | ReadonlyArray<number>) 
{
    if (Array.isArray(a)) {                              
        a.forEach(item => item.f())                         // => runtime error!
    }
    else { a.a }                                            // type error: property `a` does not exists!
}

after:

function checkArray(a: { a: 1 } | ReadonlyArray<number>) 
{
    if (Array.isArray(a)) {
        a.forEach(item => item.f())                         // type error: f does not exist on type number
    }
    else { a.a }                                            // success 
}

Object.create

before:

let o = Object.create({})                                   // any

after:

let o = Object.create({})                                   // object

Object.assign

before:

let t = Object.assign({ a: 7, b: 8 }, { b: '' })            // {a: number, b: never}

after:

let t = Object.assign({ a: 7, b: 8 }, { b: '' })            // {a: number, b: string}

Object.defineProperty

before:

const a = { a: 1 }
const r = Object.defineProperty(a, "b", { value: 1, });     // {a: number}

after:

const a = { a: 1 }
const r = Object.defineProperty(a, "b", { value: 1, });     // {a: number, readonly b: number}

Object.defineProperties

before:

const a = { a: 1 }
const rs = Object.defineProperties({ a: 1 }, {              // {a: number}
    b: { value: 1 }
});

after:

const a = { a: 1 }
const rs = Object.defineProperties({ a: 1 }, {              // {a: number, readonly b: number}
    b: { value: 1 }
});

Object.keys

A very strong temptation was to make an Object.keys(obj) returned (keys of obj)[] instead of string[]. However, in the process it was found out that such use is safe only if the received keys are used exclusively for comparison with primitives. But using them again as object type keys can lead to non-obvious errors at runtime (see for example, which will cause a runtime error). Thus, the usual redefinition of the type makes it less secure, and therefore we have abandoned such redefinition in this package. However, if you are determined, there is a safe way for you to do this using the ts-keys-turn package

before:

type O = { a: number, b: number }
const obj: O = { a: 1, b: 1 }
const keys = Object.keys(obj)                    // string[]

after ts-keys-turn:

const keys = Object.keys<O>(obj)                  // ("a" | "b")[]

However, this approach has several constraints (see the documentation)

Look up the section on configuring the package for use with Object.keys

There is also an unsafe branch that contains the aforementioned Object.keys declaration, which assumes its use without any transformations, if you are willing to take responsibility for its use as keys

const keys = Object.keys<O>({a: 1, b: 1})        // ("a" | "b")[]

DOM features:

querySelector

Improves detecting Element type from selector signature.

before:

const input = document.querySelector('input');                         // is HTMLInputElement | null
const unknown = document.querySelector('.cls');                        // is Element | null
const inputWCls = document.querySelector('input.cls');                 // is Element | null

if (divCls) {
    inputWCls.value = ''                                               // error
}

after:

const input = document.querySelector('input');                      // is HTMLInputElement | null
const unknown = document.querySelector('.cls');                     // is Element | null
const inputWCls = document.querySelector('input.cls');              // is HTMLInputElement | null
if (divCls) {
    inputWCls.value = ''                                            // success
}

querySelector<Type>

Original querySelector required just to use generic to specify returned type that may differ from the runtime:

before:

const misspell = document.querySelector<HTMLInputElement>('a.cls');         // is HTMLInputElement | null
if (misspell){
    const replaced = misspell.value.replace('.', ',')                       // runtime error!
}

after:

const misspell = document.querySelector('a.cls');                           // is HTMLInputElement | null
if (misspell){
    const replaced = misspell.value.replace('.', ',')                       // typescript error!
}

cloneNode

Now HTMLElement.cloneNode allways returns HTMLElement:

before:

const elem = document.getElementById('id')              // elem is HTMLElement
const clonedElem = elem?.cloneNode()                    // clonedElem is Node

after:

const elem = document.getElementById('id')              // elem is HTMLElement
const clonedElem = elem?.cloneNode()                    // clonedElem is HTMLElement also

currentTarget

Improved automatic type detection for the currentTarget in MouseEvent, KeyboardEvent and other user interface events (only inside addEventListener callback):

before:

let elem: HTMLDivElement = document.querySelector('div');
elem?.addEventListener('click', e => {        
    let target = e.currentTarget;                       // is EventTarget | null
})

after:

let elem: HTMLDivElement = document.querySelector('div');
elem?.addEventListener('click', e => {        
    let target = e.currentTarget;                       // is HTMLDivElement | null
})

Utility types:

Look up README.md inside corresponding declaration directory.

How to use

npm i -D types-spring

To patch the built-in types:

add types-spring to include list inside tsconfig.json:

{
    // ...,
    "include": [
        "./node_modules/**/*"
    ]    
}

Similar packages:

ts-reset

As it was said at the beginning, this package was inspired by ts-reset. At first glance, it seemed that the ts-reset does very little: it just overrides in tslib any to unknown type wherever possible, and contains two useful improvements for Array.indexOf and Array.filter. However despite the fact that in this one there are not so much features, it is very profound and I would say that the author is very scrupulous about safing.

Compatibility

Despite the small contribution of ts-reset, I was very tempted to use some of its functions in types-spring, but I deliberately did not do it in order not to repeat what other people have already done in the best possible way before me. I consider ts-reset as be a fundamental package, and the best thing to do today is to use these two these packages (ts-reset and types-spring) together

types-fest

This is a awesome package with a huge number of utility types. When I started working on types-string, I didn't know anything about it. However, when I got awared, to my surprise found that most of them (with the exception of just two) do not overlap with types-spring! It turns out that these are completely different packages with different tools, since their authors think differently.

Compatibility

types-spring and types-fest may well complement each other. Of course, that's so

Licence

MIT

GitHub