Skip to content

Instantly share code, notes, and snippets.

View Willmo36's full-sized avatar

Max Willmott Willmo36

  • SkipTheDishes
  • Saskatoon
View GitHub Profile
@Willmo36
Willmo36 / cap-kebab.ts
Last active February 6, 2024 20:28
TypeScript Lambda@edge enforce Capitalized-Header-Keys
type CapKebabCase<S extends string> = S extends `${infer A}-${infer B}` ? `${Capitalize<A>}-${CapKebabCase<B>}` : Capitalize<S>;
declare function test<S extends string>(s: S & CapKebabCase<S>): void
test("hello-there")
test("Hello-there")
test("Hello-There")
@Willmo36
Willmo36 / index.html
Created July 20, 2023 19:51
ImportMap module federation
<html>
<body>
<script type="importmap">
{
"imports": {
"moduleA": "/moduleA.js",
"moduleB": "/moduleB.js",
"react": "https://esm.sh/react@17"
},
"scopes": {
@Willmo36
Willmo36 / variadic-curry.ts
Created December 13, 2021 19:06
TypeScript variadic currying
type ArgsToFunc<Args extends [...any]> = Args extends [infer LastArg, infer Result]
? (a: LastArg) => Result //last argument case
: Args extends [infer Arg, ...infer Args, infer Result] // n-1 argument case
? (a: Arg) => ArgsToFunc<[...Args, Result]>
: never //Args was not a 2tuple, abort
function curry<F extends (...args: any) => any>(fn: F): ArgsToFunc<[...Parameters<F>, ReturnType<F>]> {
return null as any; //todo - I'm just playing at the type level
}
@Willmo36
Willmo36 / reducerhelpers.ts
Created June 26, 2021 18:06
Reducer helper functions
export type Action = { type: string };
export type Reducer<S, A extends Action> = (state: S, action: A) => S;
export type ReducerByAction<S, A extends Action> = A extends any
? Partial<Record<A["type"], Reducer<S, A>>>
: never;
export type ReducerByKey<S, A extends Action> = Partial<{
[SK in keyof S]: Reducer<S[SK], A>
@Willmo36
Willmo36 / gadt.saga.ts
Created May 10, 2021 16:10
TypeScript GADT practice - Redux-saga like
import { hole, identity, pipe } from "@effect-ts/core/Function";
/** Redux Types */
/** Redux Types */
/** Redux Types */
type Reducer<S, A> = (s: S, a: A) => S;
type Store<S, A> = {
get: () => S;
dispatch: (a: A) => void;
};
@Willmo36
Willmo36 / gadt.ts
Created May 6, 2021 09:28
TypeScript GADT
function identity<T>(t:T):T{return t};
class NumExpr<A> {
readonly _tag = "num";
constructor (readonly value: number, readonly proof: (v: number) => A) {}
}
class StringExpr<A> {
readonly _tag = "str"
@Willmo36
Willmo36 / comonad.ts
Created December 14, 2020 18:24
fp-ts comonad with example
import { Comonad2C } from 'fp-ts/lib/Comonad';
import { pipe } from 'fp-ts/lib/function';
import { FunctionN } from 'fp-ts/lib/function';
import { Monoid } from 'fp-ts/lib/Monoid';
import { NonEmptyArray } from 'fp-ts/lib/NonEmptyArray';
import { pipeable } from 'fp-ts/lib/pipeable';
/**
* OOP style builder pattern but in FP
* References:
class Batching {
updateRequested = false;
async scheduleUpdate(id: number) {
if (!this.updateRequested) {
this.updateRequested = true;
this.updateRequested = await false;
this.update(id);
}
}
@Willmo36
Willmo36 / statemachines.ts
Last active November 26, 2020 17:24
TypeScript State Machines
/**
* Impl
*/
type TransitionHandler<
From extends Union,
States extends From,
Event extends Union
> = (from: From, event: Event) => States;
type Transition<
@Willmo36
Willmo36 / pattern.ts
Last active January 27, 2022 05:32
TypeScript - Generic pattern matching
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
type Union<T extends string> = Record<T, string>;
type MatchHandlers<T extends string, P extends Union<T>, R> = P extends any ? Record<P[T], (p: P) => R> : never;
type DefaultedOrFullHandlers<T extends string, P extends Union<T>, R> =
| (Partial<MatchHandlers<T, P, R>> & { otherwise: () => R })
| UnionToIntersection<MatchHandlers<T, P, R>>;
/**
* Create a match function based on the given tag property.