Skip to content

Instantly share code, notes, and snippets.

Avatar

Kevin Welcher kaw2k

View GitHub Profile
View hooks.tsx
type Loading<T extends object> =
| { loading: true }
| { loading: false; error: true }
| ({ loading: false; error: false } & T)
function usePlayer(id: PlayerId): Loading<{ data: Player }> {
const { value, loading, error } = useDocument(database.players.doc(id))
if (loading) return { loading: true }
if (error) return { loading: false, error: true }
return { loading: false, error: false, data: value.data() }
View generics.md

Hey Fam 👋

I struggled with using typescript and ramda for a long time and figured I would brain dump a little. Maybe it will help some one else! Specifically, I struggled with how typescript can't always infer generics that ramda defines. The result is writing verbose types that are not really necessary, or forcing types with as and !.

Generics are super weird when getting into them, that coupled with ramda being a monster and typescript not being able to readily infer everything is a perfect shitstorm.

Whenever I work with ramda, my workflow is:

  1. Do a thing and assign it to a variable.
  2. If the variable isn't the type I expect, jump to the definition of the function in ramda
View material-ui@next.d.ts
/// <reference types="react" />
declare namespace MaterialUI {
type ReactEl = React.ReactChild | null | boolean
export interface MuiTheme {
palette: {
primary?: string,
accent?: string,
View clickable2.tsx
import * as React from 'react';
import * as cx from 'classnames';
import Icon, { IconOptions } from './icon';
export interface IClickableIconProps {
iconName?: IconOptions;
iconPosition?: 'before' | 'after';
}
export const addClickableIcon = (children: React.ReactNode, iconName?: IconOptions, iconPosition: 'before' | 'after' = 'before') => {
if (!iconName) { return children; };
View clickable.tsx
import * as React from 'react';
import * as cx from 'classnames';
import * as Router from 'react-router';
import Icon, { IconOptions } from './icon';
/*
We have a few things that are `clickable`:
- buttons
- internal links
- external links
View setPath.js
const setPath = (value, path, json) => {
// We reached the end, return the value as a leaf
if (!path.length) return value
// Figure out if we are going down an array or object
const isArrayMatch = path[0].match(/^\[(\d+)\]$/)
const name = isArrayMatch ? isArrayMatch[1] : path[0]
// Add the value to our json recursivly
json = json || (isArrayMatch ? [] : {})
View toJson.js
const treeArray = [
{ path: 'name', value: 'name' },
{ path: 'meta.age', value: 'age' },
{ path: 'meta.eyes', value: 'eyes' },
{ path: 'friends.[0]', value: 'friends 0' },
{ path: 'friends.[1]', value: 'friends 1' },
{ path: 'friends.[2]', value: 'friends 2' },
{ path: 'friends.[3].name', value: 'friends 3 name' },
]
View tree.ts
export type Tree<T> = Leaf<T> | TreeNodeArray<T> | TreeNodeObject<T>;
type GenericObject<T> = { [key: string]: T };
type ChildrenArray<T> = Tree<T>[];
type ChildrenObject<T> = GenericObject<Tree<T>>
function mapObj<T, U>(fn: ((value: T, key: string) => U), obj: GenericObject<T>): GenericObject<U> {
let ret = {};
View aggregate-comparators.ts
const { find, identity, toPairs, compose, map, curry } = require('ramda');
/* tslint:disable: no-any */
type AnyType = any;
/* tslint:enable: no-any */
type TComparator = (a: AnyType, b: AnyType) => number;
type TObjectComparator = {
[key: string]: TComparator;
View functors-e16.js
function map(transformation, data) {
return data.map(transformation);
}
map(addOne, [1, 2, 3]);
map(addOne, listNode(1, listNode(2, listNode(3))));
map(addOne, treeNode(1, treeNode(2), treeNode(3)));