Skip to content

Instantly share code, notes, and snippets.

View brettinternet's full-sized avatar
👋

Brett brettinternet

👋
View GitHub Profile
@brettinternet
brettinternet / never.ts
Last active June 28, 2021 22:13
`never` in TypeScript is an example of a bottom type
/**
* @source https://github.com/mike-works/typescript-fundamentals/blob/4e5782e00ed942ffe8770a694122190b6ed69b95/notes/6-guards-and-extreme-types.ts
* A bottom type is a type case that won't match - this is `never` in TypeScript
*/
class UnreachableError extends Error {
constructor(val: never, message: string) {
super(`TypeScript thought we could never end up here\n${message}`);
}
}
@brettinternet
brettinternet / type-guards.ts
Last active July 3, 2021 00:32
TypeScript type guards
/**
* @source https://github.com/mike-works/typescript-fundamentals/blob/4e5782e00ed942ffe8770a694122190b6ed69b95/notes/6-guards-and-extreme-types.ts
*/
if (typeof myUnknown === "string") {
// in here, myUnknown is of type string
myUnknown.split(", "); // ✅ OK
}
if (myUnknown instanceof Promise) {
@brettinternet
brettinternet / branded-types.ts
Last active June 28, 2021 21:48
Branded types with TypeScript
/**
* @source https://github.com/mike-works/typescript-fundamentals/blob/4e5782e00ed942ffe8770a694122190b6ed69b95/notes/6-guards-and-extreme-types.ts
* Helps guard against accidentally matching a type that might otherwise be easy to mismatch
*/
// Brand A
interface BrandedA {
__this_is_branded_with_a: "a"; // some unique primitive brand
}
@brettinternet
brettinternet / package.json
Created January 1, 2021 00:54 — forked from mnpenner/package.json
Rollup Plugin: Pug
{
"license": "UNLICENSED",
"dependencies": {
"fastify": "^3.9.2",
"fastify-cookie": "^5.1.0",
"fastify-sensible": "^3.1.0",
"google-auth-library": "^6.1.3",
"lodash": "^4.17.20",
"pug": "^3.0.0",
"pug-runtime": "^3.0.0"
@brettinternet
brettinternet / lazy-load-youtube.html
Created December 2, 2020 03:16
Lazy load embedded YouTube videos
<!-- Source: https://css-tricks.com/lazy-load-embedded-youtube-videos/ -->
<!-- Example: https://codepen.io/chriscoyier/pen/GRKZryx -->
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/Y8Wp3dafaMQ"
srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/Y8Wp3dafaMQ?autoplay=1><img src=https://img.youtube.com/vi/Y8Wp3dafaMQ/hqdefault.jpg alt='Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition'><span>▶</span></a>"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
@brettinternet
brettinternet / union-mutually-exclusive.ts
Last active August 3, 2020 01:40
Mutually exclusive union with optional properties
// https://www.typescriptlang.org/play/?ssl=12&ssc=37&pln=12&pc=43#code/LAKALgngDgpgBANQIYBsCuMDOAeAKnGADzBgDsATTOAbwF8A+OAXjlwG0BrGCAewDNWAXQDcoUJFis0UFAEsAXjDwFiZSjVptBjFgAVZAYw54ANHACihA+nJKuvAbjOWwAJyQGw2e-w1azmG6ypADmjAA+cKRoALYARjCu9PSiIOLQ8ADCABY8PJhK+EQkFFR0OoioGDjUoHBwbADScMFwPo6CAFysTYJwAGQ0dfUNALItpJXoWNjUDQAyE23cvgDyMbJeTnCN9F3LDj3zfQyCAPzdaBQwfMEw5MO0oAypoERQPK5gcBLwq6QwVZ8ZTFNRlTTaZhwHJ5Ap4aRyRR4ZKvEDBEiuPgeLJIb61EAjFqYTK4i4-VwYYb1AxoEhkgDkECw9OeYjRpAxWIM8AAIjwQkMCSNZJg+SEyW4MKlCdkkFAoBAGa4YKgUBAWSAnml2ZzsXAAEKyVzkQWEkWG40SikwaUjPhqskARlZ2t+cAAgqRZDFUFD-oDgWwSWAzGKzBbyNpUQYeKRAnAkJgCl8oSDVKU4FcOKQeAB3Uj0AAUYG6uAAlMxGHRUYnk15Pd7UEW5iKxd1JTAzLL5RBuvTlar1XBaGXUrXEvWvT6UM2icH29au3KFX2Byg1fTh6O4AB6HcEVyuT6gIA
type Values<T extends {}> = T[keyof T];
type Tuplize<T extends {}[]> = Pick<T, Exclude<keyof T, Extract<keyof {}[], string> | number>>;
type Choose<T extends {}> = Values<{
[K in keyof T]: T[K] & {
[M in Values<{ [L in keyof Omit<T, K>]: keyof T[L] }>]?: undefined
}
}>;
@brettinternet
brettinternet / file-watch.ts
Created July 9, 2020 04:05
Watch for write changes to files and move
import chokidar from 'chokidar'
import { existsSync, moveSync, removeSync } from 'fs-extra'
import { join, basename } from 'path'
type WatchFiles = string | string[]
interface OptionsArg {
/**
* Seconds to wait for files to appear
* @default 60
@brettinternet
brettinternet / current-state.hook.ts
Created May 20, 2020 22:48
Get the latest value in functional component
import {
Dispatch,
MutableRefObject,
SetStateAction,
useEffect,
useRef,
useState,
} from 'react'
export type CurrentStateType<T> = [
@brettinternet
brettinternet / CatchOrCallback.js
Last active December 10, 2019 20:04
.Then Callback vs .Catch and how they're scoped
Promise.resolve()
.then(() => {
throw new Error('This will be handled in the next .then(, err), OR in a .catch'); // comment this line to see the next error handled
})
.then(() => {
throw new Error('This will only be handled in a .catch');
}, error => {
// an alternative to .catch with less scope
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
// thus, with this method there's a block of code where errors could be left unhandled
@brettinternet
brettinternet / README.md
Created November 12, 2019 16:31
Event Delegation example

Event delegation is a technique involving adding event listeners to a parent element instead of adding them to the descendant elements. The listener will fire whenever the event is triggered on the descendant elements due to event bubbling up the DOM.

The benefits of this technique are:

  • Memory footprint goes down because only one single handler is needed on the parent element, rather than having to attach event handlers on each descendant.
  • There is no need to unbind the handler from elements that are removed and to bind the event for new elements.
Resources