Skip to content

Instantly share code, notes, and snippets.

import Controller from '@ember/controller';
export default class ApplicationController extends Controller {
appName = 'Ember Twiddle';
}
declare const EmailTag: unique symbol;
type Email = string & typeof EmailTag;
function isEmail(email: string): email is Email {
return /@/.test(email);
}
function createEmail(email: string): Email;
function createEmail(username: string, domain?: string): Email {
if (domain) {
@chriseppstein
chriseppstein / pgp_public_key.txt
Created April 17, 2018 16:36
PGP public key for security@linkedin.com
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFhrJiwBEADCAf2/KIky7iVU+OnU16vXs9yewnevPCkKTNwWfcPbmxGGiN/n
DAAUOxJ62XiXC5MKVThr2od9kl/VtBI9IYtAqXCQ/hA9yTUJ47/ZcM55RQqyiwjP
DWjZXzp5V2P+/Ny3nyST1Z7/kH6GlFZ6+nPOkeQSQyYjwqPqwz2UZL0h+rZHTlzE
edGlilStHFOuwdqfsDZtb0qGaXT7AN1BPmn9ulzNG/8lcssIGio3/xLJ5fLCfoqx
Qb0iZPtiOCiPSJwM484a8JgHrwmsoBlOJmJ6tZc9HohU4OFgZyCwnxE0fTcNvuDt
+JDCNCumpoa8/6x7U0eIg2ghJ9EDRliy1O5VxHLttOz/I+1guEedk/EcOx/5Q1Zz
BPdJuBrB2ryJ1GDEJi+Cy3MCI48VTc3/4toGarGyH/gaVWOfFt1QJAaXPPFkij5Y
egfAy6yQYY0uYGml65VK0QdsRuZESjAYkXcUpdOiGdrUp77JwgNEuMmBZ7Q1d3jn
@chriseppstein
chriseppstein / DependenciesInPublicAPIs.md
Last active May 4, 2023 16:26
If you keep getting "Two different types with this name exist, but they are unrelated." from TypeScript, here's what you need to do to fix it.

Two different types with this name exist, but they are unrelated.

I'm a little slow, so maybe everyone else already realized this, but after struggling for almost a year with periodic "Two different types with this name exist" error from typescript, I've realized it is actually really helpful error and it highlights a real problem that I've failed to understand until this week.

I've been working around this issue by making sure that my libraries with common dependencies are always on the same version for some of our shared library dependencies. This works because package managers dedup the same version of a dependency. But when the versions diverge you get different instances of the library. In this mode, Good Guy TypeScript is telling us "Hey you're comparing values and types from different instances of the same library and that's a Bad Idea."

{
  line = $0
  while (match(line, /^(.*)spacing\(([0-9\.]+)\)(.*)$/, groups)) {
    line = groups[1] "SPACING(" (groups[2] * 2) ")" groups[3]
  }
  gsub(/SPACING/, "spacing", line)
  print line
}
/**
* Types representing having no value for various reasons.
*/
export type nothing = null | undefined | void;
export function isNothing(v: whatever): v is nothing {
return v === null || v === undefined;
}
/**
* Falsy in JS isn't always what you want. Somethings aren't nothings.
@chriseppstein
chriseppstein / GenericMappedTypes.ts
Created January 29, 2018 19:22
This is my syntax idea for generating a subset of TypeScript properties for more interesting mapped types.
type Fn<RV, ARGS = any[]> = (...args: ARGS) => RV;
type Maybe<T> = {
// * Mapped types would no longer be limited to a single property map expression. But for each key, only the
// first expression that matches the key would be used.
// * `keyof SOURCE_TYPE extending NARROW_TYPE` is narrowing expression to limit which keys of SOURCE_TYPE
// are enumerated. Only keys having a type that can extend the NARROW_TYPE are enumerated.
// * The syntax for a mapped property type would be extended to allow a generic type declaration, this allows
// the generic to represent the actual concrete type of the key and then be passed along to the type of the
// mapped property.
import { something, defined, TypeGuard, FunctionCall0, FunctionCall1, FunctionCall2, FunctionCall3, FunctionCall4 } from "./UtilityTypes";
import { isObject, whatever } from "./index";
/**
* Maybe.ts - A TypeScript implementation of the Maybe Monad.
* ==========================================================
*
* Usually a Maybe is strong type with methods, but that approach, I felt,
* would lead to poor performance characteristics and also not take full
* advantage of TypeScript's specific approach to types using type guards.

ItemType Generic Utility Type

This is to describe the situation where one might want to use the type of an array indirectly.

The ItemType generic is sugar over an existing capability in TypeScript to access the type information of the Array generic and make accessing that type more legible to the reader. But a few people replied with "huh, I don't think you want to do that", and to their point, I agree... mostly.

It's almost always better to declare a variable to be of the Array's type directly.

import { Queue } from "typescript-collections";
const subsetFunctions = new WeakMap<SubsetTree<any>, IsSubsetFunction<any>>();
const subsetMemos = new WeakMap<IsSubsetFunction<any>, WeakMap<any, WeakMap<any, boolean>>>();
/**
* A subset tree self organizes new nodes such that they will be added to place
* in the tree where it is guaranteed that all nodes in the tree that have
* values that are subsets of the value in the new node are descendants of that