Layer 1
Navigate back to the homepage

I Started To Build Something

Chris Marrin
April 9th, 2021 · 2 min read

Getting Started

I wanted this to be pure TS from the start. So I quickly set up a barebones repo with just the absolute necessary pieces.

1"dependencies": {
2 "css-mediaquery": "^0.1.2",
3 "object-resolve-path": "^1.1.1",
4 "typescript": "^4.2.3"
5}

We set up some simple build scripts.

1"scripts": {
2 "build": "rimraf dist && tsc",
3 "watch": "tsc --watch"
4},

And off we go. The first thing I did was the bring the original source files over, and rename them and adjust some imports. I haven’t turned all of TS nice strict rules on yet, so even tho it’s just pure js, it’s still valid, and it compiles.

Our First Step

Ok, I know that react-native-extended-stylesheet has some built in types, because we don’t get the module warning when trying to import it. Let’s see what it looks like.

1declare namespace EStyleSheet {
2 type AnyObject<T = {}> = T & {[key: string]: any};
3 export function create<T>(styles: AnyObject<T>): AnyObject<T>;
4}

I snipped out just the part we care about. We can see that the type basically allows us to give it any object that has string type keys and returns any object. This is great, as it allows us to still use the lib in our TS projects, and this is a lib you want to use. BUT, like I had mentioned, we obviously won’t get any type info from this! That’s what we want to fix.

Having used the StyleSheet class from react-native I knew that the DefinitelyTyped repo had some types for that class that really helped me out when first working with react-native so let’s look there.

1export namespace StyleSheet {
2 type NamedStyles<T> = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };
3
4 /**
5 * Creates a StyleSheet style reference from the given object.
6 */
7 export function create<T extends NamedStyles<T> | NamedStyles<any>>(styles: T | NamedStyles<T>): T;
8}

Link to location in code

This looks super useful right off the bat. This allows us to say for each key in this object, it will be either a ViewStyle, TextStyle, or ImageStyle. For a simple first step to improve our types, lets add these definitions to our library.

1export type NamedStyles<T> = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };
2
3 export class EStyleSheet {
4
5 /** SNIP **/
6 /**
7 * Creates stylesheet that will be calculated after build
8 * @param {Object} obj
9 * @returns {Object}
10 */
11 create<T extends NamedStyles<T> | NamedStyles<any>>(styles: T | NamedStyles<T>): T {
12 const sheet = new Sheet(styles);
13 this.sheets.push(sheet);
14 if (this.built) {
15 sheet.calc(this.globalVars);
16 }
17 return sheet.getResult();
18 }

Alright, let’s give this a go.

Alt text

Excellent! At this point, if you’re familiar with EStyleSheet, you may have an idea of what our next problem is going to be.

Alt text

ARGH! It hates @media queries! And we really want those to work nice! So, how we figure that out will be the content of the next article. However, before I got much further, I started to add some of that nice tooling you want when you’re creating/maintaining a library.

Adding ESLint and Prettier

Alright, first we want to add ESLint to our project. Adding ESLint to your project allows you to use it’s static code analyzer to indentify common issues in JS/TS code! If you’re using VS Code, it will even show up in the problems tab. Many ESLint rules come with auto-fix, so that much of the grunt work is handled by the tooling.

First we add the new packages we need.

1yarn add -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier

And we need a quick .eslintrc.js file to set our config

1module.exports = {
2 root: true,
3 parser: '@typescript-eslint/parser',
4 plugins: [
5 '@typescript-eslint',
6 ],
7 extends: [
8 'eslint:recommended',
9 'plugin:@typescript-eslint/recommended',
10 ],
11 };

You may want to adjust some of the options of prettier, but I won’t cover that here. With that out of the way, our linter finds some issues and we’ll be cleaning those up as we go.

The next article will cover how we’ll add nice accurate types to our create({}) method.

Photo by Markus Spiske on Unsplash

More articles from Chris Marrin

I wanna build something...

Preamble (Indulge Me) I've long long long wanted to build something... But what? Always the big question. Sometimes you get something that…

April 3rd, 2021 · 2 min read
© 2021 Chris Marrin
Link to $https://twitter.com/marrin519Link to $https://github.com/chrismarrin