Skip to content

Instantly share code, notes, and snippets.

/**
* testがundefined or nullでなければthenを実行
* そうでなければfallbackを実行する
*
* @template R1
* @template R2
* @template R3
* @param {((() => R1) | R1)} test
* @param {(a: R1) => R2} then
* @param {() => R3} [fallback]
@typoerr
typoerr / set.ts
Last active June 16, 2023 16:37
Typesafe immutable set with lodash/fp/set
/* tslint:disable:max-line-length */
const _ = {
set: require('lodash/fp/set'),
};
function set<O, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4], K6 extends keyof O[K1][K2][K3][K4][K5], K7 extends keyof O[K1][K2][K3][K4][K5][K6], K8 extends keyof O[K1][K2][K3][K4][K5][K6][K7], K9 extends keyof O[K1][K2][K3][K4][K5][K6][K7][K8], K10 extends keyof O[K1][K2][K3][K4][K5][K6][K7][K8][K9], V>(obj: O, path: string | [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10], val: V): O & Record<K1, Record<K2, Record<K3, Record<K4, Record<K5, Record<K6, Record<K7, Record<K8, Record<K9, Record<K10, V>>>>>>>>>>;
function set<O, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4], K6 extends keyof O[K1][K2][K3][K4][K5], K7 extends keyof O[K1][K2][K3][K4][K5][K6], K8 extends keyof O[K1][K2][K3][K4][K5][K6][K7], K9 extends keyof O[K1][K2][K3][K4][K5][K6][K7
@typoerr
typoerr / update.ts
Created February 21, 2017 06:53
Typesafe immutable update with lodash/fp/update
/* tslint:disable:max-line-length */
const _ = {
update: require('lodash/fp/update'),
};
function update<O, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4], K6 extends keyof O[K1][K2][K3][K4][K5], K7 extends keyof O[K1][K2][K3][K4][K5][K6], K8 extends keyof O[K1][K2][K3][K4][K5][K6][K7], K9 extends keyof O[K1][K2][K3][K4][K5][K6][K7][K8], K10 extends keyof O[K1][K2][K3][K4][K5][K6][K7][K8][K9], V>(obj: O, path: string | [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10], updater: (v: O[K1][K2][K3][K4][K5][K6][K7][K8][K9][K10]) => V): O & Record<K1, Record<K2, Record<K3, Record<K4, Record<K5, Record<K6, Record<K7, Record<K8, Record<K9, Record<K10, V>>>>>>>>>>;
function update<O, K1 extends keyof O, K2 extends keyof O[K1], K3 extends keyof O[K1][K2], K4 extends keyof O[K1][K2][K3], K5 extends keyof O[K1][K2][K3][K4], K6 extends keyof O[K1][K2][K3][K4][K5], K7 extends keyof O[K1][K2][K3][K4][K5][K6], K8 extends keyof O[K1][K2]
@typoerr
typoerr / typesafe-flux.ts
Last active March 11, 2017 05:47
Minimal TypeSafe Flux
type ReduceMap<S, T> = {
[P in keyof T]: (state: S, payload: T[P]) => S
};
const createStore = <S, T>(initState: S, reduceMap: ReduceMap<S, T>) => {
let $state = initState;
const $listeners: Function[] = [];
return {
get listenerCount() {
return $listeners.length;
@typoerr
typoerr / immutable-updater.ts
Created March 18, 2017 01:44
immtable-updater
/* API */
export function getIn(src: object, path: _.Path) {
return _.parsePath(path).reduce((acc, k) => (acc as any)[k], src);
}
export function hasIn(src: object, path: _.Path) {
return _.existy(getIn(src, path));
}
export function setIn(src: object, path: _.Path, value: object) {
@typoerr
typoerr / zen-observable.d.ts
Last active March 23, 2017 12:41
zen-observable.d.ts
declare module 'zen-observable' {
export = Observable;
class Observable<T> {
constructor(subscriber: SubscriberFunction<T>);
subscribe(observer: Observer<T>): Subscription;
subscribe(observer: (value: T) => any): Subscription;
forEach(callback: (value: T) => any): Promise<void>;
map<U>(callback: (value: T) => U): Observable<U>;
@typoerr
typoerr / ieh.ts
Last active April 4, 2017 05:01
immutable entries collection helpers
export type Entries<K, V> = Entry<K, V>[];
export type Entry<K, V> = [K, V];
export type Iteratee<K, V, R> = (v: V, k: K, index: number, src: Entries<K, V>) => R;
namespace util {
export function existy(v: any) {
return !(v === null || v === undefined);
}
export function includes<T>(src: T[], target: T) {
return src.indexOf(target) >= 0;
@typoerr
typoerr / observable.ts
Last active April 15, 2017 02:07
Observable実装
// [実装して学ぶRxJS - undefined](http://blog.bokuweb.me/entry/min-rxjs)
interface IObserver<T> {
next: (v: T) => any;
complete: () => any;
}
interface Producer<T> {
(observer: IObserver<T>): any;
}
@typoerr
typoerr / transaction.ts
Last active April 18, 2017 00:45
indexdDBのtransaction抽象とrequest抽象
////////////////////// Transaction //////////////////////
export function trx<T>(scope: string | string[], mode: 'r' | 'rw', executor: trx.Executor<T>) {
return (onResolve: Function, onReject: Function) => (db: IDBDatabase, KeyRange: typeof IDBKeyRange) => {
const $trx = db.transaction(scope, trx.parseTrxMode(mode));
const i = executor(new Request<T>(KeyRange));
$trx.addEventListener('error', function () {
onReject(this.error);
});
/*
* 指定count回目の呼び出しでcallbackを叩く関数
*/
export function onlyThatTime(n: number, callback: () => any): () => void;
export function onlyThatTime<A>(n: number, callback: (a: A) => any, init?: [A]): (a: A) => void;
export function onlyThatTime<A1, A2>(n: number, callback: (a1: A1, a2: A2) => any, init?: [A1, A2]): (a1: A1, a2: A2) => void;
export function onlyThatTime<A1, A2, A3>(n: number, callback: (a1: A1, a2: A2, a3: A3) => any, init?: [A1, A2, A3]): (a1: A1, a2: A2, a3: A3) => void;
export function onlyThatTime(n: number, callback: Function, init: any[] = []): Function {
let called = false;
let count = 0;