Skip to content

Instantly share code, notes, and snippets.

Oliver Joseph Ash OliverJAsh

Block or report user

Report or block OliverJAsh

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
@OliverJAsh
OliverJAsh / foo.md
Last active Aug 23, 2019
Naming pipeable operators
View foo.md

Naming pipeable operators

Many libraries are moving from instance methods to [pipeable operators] (e.g. RxJS, fp-ts, idb-keyval, Fluture, date-fns) because they have better bundling performance.

This works really well when you're only importing pipeable operators for one type (e.g. Observable from RxJS), but if we're working with multiple types (e.g. Observable and Option from fp-ts) in the same file, you will inevitably face the problem of naming conflicts. For example:

import { map } from "rxjs/operators";
import { map } from "fp-ts/lib/Option";
View api.js
// ./api.js
export const getPhoto = () => {
/**/
};
export const getUser = () => {
/**/
};
import * as Api from "./api";
View foo.md

Named namespace imports

If you're organising JavaScript/TypeScript code into [modules], at some point you're going to need to consider how you're naming your imports and exports. At Unsplash, the issue we've found is that names either have too little information or too much—the former leads to naming conflicts and the latter leads to very long names.

[Namespace imports][namespace imports] are designed to help with this, but they have several disadvantages when compared with [named imports]. This article introduces named namespace imports, a technique which we've adopted at Unsplash to combine (as the name suggests) the best of both [namespace imports] and [named imports].

Namespace imports

Imagine we have an API module which exports some functions corresponding to API endpoints:

View foo.md
Dev UX: auto imports Dev UX: contextual naming Perf: tree shaking Dev UX: namespace/type merging
namespace import not yet yes maybe no
TS namespace yes yes no yes
types: namespace import / values: named import not yet / yes yes / no yes no
types: TS namespace / values: named import yes yes / no yes yes
@OliverJAsh
OliverJAsh / foo.ts
Created Aug 9, 2019
A negate function for type guards
View foo.ts
type TypeGuard<T, U extends T> = (value: T) => value is U;
const negate = <T, U extends T>(
typeGuard: TypeGuard<T, U>,
): TypeGuard<T, Exclude<T, U>> => (value): value is Exclude<T, U> =>
typeGuard(value) === false;
// Example
const checkIsArray = <T>(value: T | any[]): value is any[] =>
@OliverJAsh
OliverJAsh / test.ts
Created Aug 2, 2019
TypeScript narrow non-discriminated union
View test.ts
{
type AncestryType = {
type: string;
};
type AncestryCategory = {
type: string;
category: string;
};
@OliverJAsh
OliverJAsh / env.ts
Created Aug 2, 2019
TypeScript narrowed union is lost inside function scopes
View env.ts
export type Foo = {
foo: string;
};
export type Bar = {
bar: string;
};
export type Value = Foo | Bar;
export declare const value: Value;
View foo.sh
#!/bin/bash
# https://junegunn.kr/2016/07/fzf-git/
# https://hackernoon.com/be-125-more-efficient-with-git-60556a1ce971
# https://github.com/fcsonline/dotfiles/blob/master/git/gitconfig
# https://github.com/junegunn/fzf/wiki/Examples#git
# TODO: incorporate fix into this?
# TODO: select commits for editing, generate rebase from that
View _git-merge-pr
#compdef git-merge-pr
_git-merge-pr () {
# Multiple lines = -l
# compadd -l -d "('foo:a b c' 'bar:d e f')" foo bar
# lines=('foo:a b c' 'bar:d e f')
# compadd -l -d lines foo bar
# lines=('foo:a b c' 'bar:d e f')
@OliverJAsh
OliverJAsh / foo.ts
Created Aug 1, 2019
TypeScript + React: convert render prop component to HOC
View foo.ts
import { ComponentType, ReactElement } from 'react';
import React = require('react');
type RenderPropComponent = ComponentType<{ children: () => ReactElement }>;
const RenderProp: RenderPropComponent = ({ children }) => (
<div>{children()}</div>
);
const renderPropToHoc = (RenderPropComponent: RenderPropComponent) => <P,>(
You can’t perform that action at this time.