Skip to content

Instantly share code, notes, and snippets.

View colinhacks's full-sized avatar

Colin McDonnell colinhacks

View GitHub Profile
import { typeDefs as prismaSchema } from './client/prisma-schema';
const prismaAST = gql`
${prismaSchema}
`;
/*
remove the built-in Mutation and Query objects
from the Prisma Client schema
*/
@colinhacks
colinhacks / gist:3c5c46e6934720a5f4dae16d01dbe6da
Created March 20, 2019 16:40
Generated TypeORM query with nested relations
SELECT DISTINCT "distinctAlias"."user_id" AS "ids_User_id"
FROM (SELECT "user"."id" AS
"User_id",
"user"."createdat" AS
"User_createdAt",
"user"."updatedat" AS
"User_updatedAt",
"user"."authid" AS
"User_authId",
"user"."firstname" AS
const schema = yup.object({
asdf: yup.string(),
});
schema.validate({}); // passes
type SchemaType = yup.InferType<typeof schema>;
// returns { asdf: string }
// should be { asdf?: string }
const numList = yup
.array()
.of(yup.string())
.required();
// interpreted as a non-empty list
numList.validateSync([]); // fails
// yet the inferred type doesn't reflect this
type NumList = yup.InferType<typeof numList>;
const A = t.type({
foo: t.string,
});
const B = t.partial({
bar: t.number,
});
const C = t.intersection([A, B]);
@colinhacks
colinhacks / ts_literal_json_inference.ts
Last active March 25, 2020 21:35
Generic TypeScript function that infers the literal type of any primitive, object, or tuple (literal JSON type inference)
type Primitive = string | number | boolean | null | undefined;
type Compound<U extends Primitive = Primitive> =
| U
| { [name: string]: Compound<U> }
| []
| [Compound<U>]
| [Compound<U>, ...Compound<U>[]];
type Json<U extends Primitive> = U | Compound<U>;
// this function infers the EXACT type of the value passed into it
@colinhacks
colinhacks / _document.tsx
Last active January 12, 2023 16:44
How to support server-side rendering for plain "emotion" package in Next.js
// ⚠️ works with Emotion 10 only! ⚠️
// 1. `yarn add emotion-server`
// 2. copy the contents of this file into your `pages` directory
// 3. save it as `_document.tsx`
// should work out of the box
import Document, { Head, Main, NextScript } from 'next/document';

Emotion is my favorite CSS-in-JS library.

It's easy to define style classes (both inline or in separate files), compose them in powerful ways with the cx utility, sprinkle them into React components using the standard className attribute. There's no need to ever modify your markup/JSX to apply styles (as it should be!). Plus you only need to install a single module (yarn add emotion) and there's no complicated Babel plugin or config file to set up.

I'm currently building a Tailwind-style CSS-in-JS utility styling library (join my newsletter at the bottom of this page to stay updated!) and Emotion provides the perfect layer of abstraction to build upon.

Why @emotion/core is bad

Unfortunately everything I just said only applies to the vanilla emotion module (https://emotion.sh/docs/emotion), not the inexplicably-named @emotion/core module. @emotion/core is the React-focused Emotion wrapper that gives you some extra goodies, like server-side rendering and theming.

@colinhacks
colinhacks / toZod.ts
Created July 9, 2020 06:41
Generating schema type from TypeScript type
import * as z from 'zod';
type isAny<T> = [any extends T ? 'true' : 'false'] extends ['true']
? true
: false;
type nonoptional<T> = T extends undefined ? never : T;
type nonnullable<T> = T extends null ? never : T;
type equals<X, Y> = [X] extends [Y] ? ([Y] extends [X] ? true : false) : false;
export type toZod<T> = {
@colinhacks
colinhacks / ground_truthiness.md
Created July 31, 2020 23:55
Ground truthiness

Achieving the Holy Grail of TypeScript Data Modeling Or, a scalable solution to type complexity

For the highly abbreviated version of this, check out this comment: colinhacks/zod#53 (comment). That comment conveys why this is so exciting. If you agree then the outline below explains the context for why I think it’s so exciting and introduces a the architectural concept of “ground truthiness” which I think is a very powerful notion.

Context

This journey started in 2018 when I decided to start a company. For inexplicable reasons I decided to build an electronic medical record software, one of the most regulated and complex product categories in the world. Also I was a solo founder. Now if you’re ever tempted to do this, for the love of god, don’t. Just say no!

Since this was medical software so I wanted it to be rock solid — end to end typesafety, powerful and expressive endpoints, painless schema migration. I was deeply entrenched in vanilla JavaScript development,