Created
April 7, 2020 10:03
-
-
Save geelen/7242942912fe7cc7cb6c984ac236fc75 to your computer and use it in GitHub Desktop.
ARGH TYPESCRIPT WHY WONT YOU OBEY ME
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { css } from 'styled-components' | |
type RulesDefn = { | |
[k: string]: string | |
} | |
type TrainBuilder<T extends RulesDefn> = { | |
[k in keyof T]: TrainBuilder<T> | |
} & { | |
toString: () => string[] | |
} | |
export const px = (num: string | number) => | |
typeof num === 'string' ? num : `${num}rem` | |
const typography = { | |
small: `font-size: 1rem;`, | |
large: `font-size: 2rem;`, | |
size: (x: string | number) => `font-size: ${px(x)}`, | |
} | |
const flex: RulesDefn = { | |
default: `display: flex;`, | |
inline: `display: inline-flex;`, | |
vertical: `flex-direction: column;`, | |
align_center: `align-items: center;`, | |
align_start: `align-items: flex-start;`, | |
align_end: `align-items: flex-end;`, | |
align_baseline: `align-items: baseline;`, | |
align_stretch: `align-items: stretch;`, | |
center: `justify-content: center;`, | |
center_both: `justify-content: center; align-items: center;`, | |
justify_start: `justify-content: flex-start;`, | |
justify_end: `justify-content: flex-end;`, | |
justify_space_btw: `justify-content: space-between;`, | |
justify_space_around: `justify-content: space-around;`, | |
wrap: `flex-wrap: wrap;`, | |
fg0: `flex-grow: 0;`, | |
fg1: `flex-grow: 1;`, | |
fg2: `flex-grow: 2;`, | |
} | |
const x =css` | |
${typography.small().size(1.2).size('13px')}; | |
${sizing.height(4).pt(1)}; | |
` | |
function chain<T extends RulesDefn>(rules: T): TrainBuilder<T> { | |
class ChainLink { | |
private readonly rules: string[] | |
constructor(rules: string[]) { | |
this.rules = rules | |
} | |
toString() { | |
return this.rules | |
} | |
} | |
Object.keys(rules).forEach((option) => { | |
Object.defineProperty(ChainLink.prototype, option, { | |
get() { | |
return new ChainLink(this.rules.concat(rules[option])) | |
}, | |
}) | |
}) | |
return (new ChainLink([rules.default]) as unknown) as TrainBuilder<T> | |
// return 'foo' | |
} | |
const Flex = chain(flex) as TrainBuilder<typeof typography> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment