HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
sindresorhus
type-fest
TypeScript2019–2025
sindresorhus / type-fest

type-fest

A collection of essential TypeScript types

13Distinct people
14Mentions
0Explicit recommenders
17.5KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A collection of essential TypeScript types

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 3:56:07 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year14 dated mentions

Observed mentions: 2019-12-19 23:42:19 UTC to 2025-10-26 18:38:34 UTC.

02462019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC101
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC000
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC202
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC615
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC312

What Hacker News says

14 sources
Read the rest
r https://github.com/szmarczak/http-timer https://github.com/szmarczak/defer-to-connect https://github.com/szmarczak/cacheable-lookup https://github.com/jaredwray/cacheable https://github.com/biomejs/biome https://github.com/sindresorhus/decompress-response https://github.com/sindresorhus/mimic-response https://github.com/octet-stream/form-data-encoder https://github.com/szmarczak/http2-wrapper https://github.com/szmarczak/resolve-alpn https://github.com/sindresorhus/lowercase-keys https://github.com/sindresorhus/p-cancelable https://github.com/sindresorhus/responselike https://github.com/sindresorhus/type-fest https://github.com/sindresorhus/tagged-tag https://github.com/max-mapper/extract-zip https://github.com/sindresorhus/get-stream https://github.com/Sec-ant/readable-stream https://github.com/sindresorhus/is-stream https://github.com/thejoshwolfe/yauzl https://github.com/brianloveswords/buffer-crc32 https://github.com/andrewrk/node-pend https://github.com/i18next/i18next https://github.com/babel/babel https://github.com/microsoft/TypeScript https://github.com/lezer-parser https://github.com/lucide-icons/lucide https://github.com/mathjax/MathJax https://github.com/mermaid-js/mermaid https://github.com/moment/moment https://github.com/mozilla/pdf.js https://github.com/pixijs/pixijs https://github.com/mapbox/earcut https://github.com/primus/eventemitter3 https://github.com/matt-way/gifuct-js https://github.com/matt-way/jsBinarySchemaParser https://github.com/kaimallea/isMobile https://github.com/browserslist/caniuse-lite https://github.com/jkroso/parse-svg-path https://github.com/avoidwork/tiny-lru https://github.com/PrismJS/prism/ https://github.com/mourner/rbush https://github.com/mourner/quickselect https://github.com/remarkjs/remark https://github.com/hakimel/reveal.js https://github.com/barrysteyn/node-scrypt https://github.com/nodejs/nan https://github.com/mixmark-io/turndown https://github.com/mixmark-io/domino https://github.com/webpack/webpack https://github.com/acornjs/acorn https://github.com/nicolo-ribaudo/acorn-import-phases https://github.com/browserslist/browserslist https://github.com/web-platform-dx/baseline-browser-mapping https://github.com/kilian/electron-to-chromium https://github.com/chicoxyzzy/node-releases https://github.com/browserslist/update-db https://github.com/lukeed/escalade https://github.com/alexeyraspopov/picocolors https://github.com/samccone/chrome-trace-event https://github.com/webpack/enhanced-resolve https://github.com/isaacs/node-graceful-fs https://github.com/webpack/tapable https://github.com/guybedford/es-module-lexer https://github.com/eslint/js https://github.com/browserify/events https://github.com/fitzgen/glob-to-regexp https://github.com/isaacs/node-graceful-fs https://github.com/npm/json-parse-even-better-errors https://github.com/webpack/loader-runner https://github.com/jshttp/mime-types https://github.com/jshttp/mime-db https://github.com/suguru03/neo-async https://github.com/webpack/schema-utils https://github.com/ajv-validator/ajv https://github.com/epoberezkin/fast-deep-equal https://github.com/fastify/fast-uri https://github.com/epoberezkin/json-schema-traverse https://github.com/floatdrop/require-from-string https://github.com/ajv-validator/ajv-formats https://github.com/ajv-validator/ajv-keywords https://github.com/DefinitelyTyped/DefinitelyTyped https://github.com/webpack-contrib/terser-webpack-plugin https://github.com/jridgewell/sourcemaps https://github.com/jestjs/jest https://github.com/yahoo/serialize-javascript https://github.com/browserify/randombytes https://github.com/terser/terser https://github.com/tj/commander.js https://github.com/evanw/node-source-map-support https://github.com/LinusU/buffer-from https://github.com/mozilla/source-map https://github.com/webpack/watchpack https://github.com/webpack/webpack-sources https://github.com/eemeli/yaml
In Less is safer: Reducing the risk of supply chain attacks
> I also don't really get what this branded type adds beyond the typical way of doing it Your example is a (non-working) tagged union, not a branded type. Not sure about op's specific code, but good branded types [0]: 1. Unlike your example, they actually work (playground [1]): type Hash = string & { tag: "hash" } const doSomething = (hash: Hash) => true doSomething('someHash') // how can I even build the type !?!? 2. Cannot be built except by using that branded type -- they're actually nominal, unlike your example where I can literally just add a `{ tag: 'hash' }` prop (or even worse, have it in a existing type and pass it by mistake) 3. Can have multiple brands without risk of overlap (this is also why your "wrap the type" comment missed the point, branded types are not meant to simulate inheritance) 4. Are compile-time onl
Read the rest
y (your `tag` is also there at runtime) 5. Can be composed, like this: type Url = Tagged<string, 'URL'>; type SpecialCacheKey = Tagged<Url, 'SpecialCacheKey'>; See my other comment for more on what a complete branded type offers https://news.ycombinator.com/item?id=40368052 [0] https://github.com/sindresorhus/type-fest/blob/main/source/o... [1] https://www.typescriptlang.org/play/?#code/C4TwDgpgBAEghgZwB...
In Branded types for TypeScript
> In all scenarios [...] there is no reason for wanting nominal typing. Hard disagree. It's very useful to e.g. make a `PasswordResetToken` be different from a `CsrfToken`. Prepending a template literal changes the underlying value and you can no longer do stuff like `Buffer.from(token, 'base64')`. It's just a poor-man's version of branding with all the disadvantages and none of the advantages. You can still `hash.toUpperCase()` a branded type. It just stops being branded (as it should) just like `toUpperCase` with `hashed_` prepended would stop working... except `toLowerCase()` would completely pass your template literal check while messing with the uppercase characters in the token (thus it should no longer be a token, i.e. your program is now wrong). Additionally branded types can have multiple brands[0] that will work as you expect. S
Read the rest
o a user id from your DB can be a `UserId`, a `ModeratorId`, an `AdminId` and a plain string (when actually sending it to a raw DB method) as needed. Try doing this (playground in [1]) with template literals: type UserId = Tagged<string, 'UserId'> type ModeratorId = Tagged<UserId, 'ModeratorId'> // notice we composed with UserId here type AdminId = Tagged<UserId, 'AdminId'> // and here const banUser = (banned: UserId, banner: AdminId) => { console.log(`${banner} just banned ${banned.toUpperCase()}`) } const notifyUser = (banned: UserId, notifier: ModeratorId) => { console.log(`${notifier} just notified ${banned.toUpperCase()}`) // notice toUpperCase here } const banUserAndNotify = (banned: UserId, banner: ModeratorId & AdminId) => { banUser(banned, banner) notifyUser(banned, banner) } const getUserId = () => `${Math.random().toString(16)}` as UserId const getModeratorId = () => // moderators are also users! // but we didn't need to tell it explicitly here with `as UserId & ModeratorId` (we could have though) `${Math.random().toString(16)}` as ModeratorId const getAdminId = () => // just like admins are also users `${Math.random().toString(16)}` as AdminId const getModeratorAndAdminId = () => // this is user is BOTH moderator AND admin (and a regular user, of course) // note here we did use the `&` type intersection `${Math.random().toString(16)}` as ModeratorId & AdminId banUser(getUserId(), getAdminId()) banUserAndNotify(getUserId(), getAdminId()) // this fails banUserAndNotify(getUserId(), getModeratorId()) // this fails too banUserAndNotify(getUserId(), getModeratorAndAdminId()) // but this works banUser(getAdminId(), getAdminId()) // you can even ban admins, because they're also users console.log(getAdminId().toUpperCase()) // this also works getAdminId().toUpperCase() satisfies string // because of this banUser(getUserId(), getAdminId().toUpperCase()) // but this fails (as it should) getAdminId().toUpperCase() satisfies AdminId // because this also fails You can also do stuff like: const superBan = <T extends UserId>(banned: Exclude<T, AdminId>, banner: AdminId) => { console.log(`${banner} just super-banned ${banned.toUpperCase()}`) } superBan(getUserId(), getAdminId()) // this works superBan(getModeratorId(), getAdminId()) // this works too superBan(getAdminId(), getAdminId()) // you cannot super-ban admins, even though they're also users! [0] https://github.com/sindresorhus/type-fest/blob/main/source/o... [1] https://www.typescriptlang.org/play/?#code/CYUwxgNghgTiAEYD2...
In Branded types for TypeScript
JSON has always accepted "bare" values (try JSON.parse in the browser devtools). In the space, a valid json document is any of those "bare" values, or an array or object of those. All of the answers in your linked StackOverflow also mention this. For example, the spec explainer at https://www.json.org/ (on the righ-hand), tells you that a `json` document is an `element`, which is a `value` surrounded by any or no whitespace. This `value` can be a literal, or an object or array. For an (IMO) easier definition, you can check how JSON values are usually defined in TypeScript e.g. https://github.com/sindresorhus/type-fest/blob/main/source/b...
In Documentation for the JSON Lines text file format
Some folks have built whole SQL databases and DSL compilers in the TS type system. These tend to be toy projects with disclaimers not to use them. But the type system being Turing complete[0] (for better or worse), pretty much whatever you can imagine. This project[1] is one I actually return to frequently for practical ideas. 0: https://github.com/microsoft/TypeScript/issues/14833 1: https://github.com/sindresorhus/type-fest
In JavaScript and TypeScript features of the last 3 years
> TypeScript's type annotations are really a DSL embedded into JavaScript. And they can, and, depending on the problem at hand, should be treated as such. I think this is the key. If treated as you describe, meaning the advanced types are well-written, well-documented, and well unit-tested as if they are "true" code, then using them shouldn't be too much of an issue. However, I think people often just assume that the types aren't "real" code and thus the normal concepts of good software engineering don't apply and type monstrosities which nobody can understand result. Imagine if this code[0] wasn't well-documented, fairly clearly written, and also tested. It would definitely be a liability in a codebase. In addition, the rules of how advanced TypeScript concepts work can be quite nuanced and not always extremely well defined, so you can e
Read the rest
nd up in situations where nobody even _really_ understands why some crazy type works. [0]: https://github.com/sindresorhus/type-fest/blob/2f418dbbb6182...
In Extreme explorations of TypeScript's type system

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.