typescript for creating personalized theme based styled components

After conducting some research online, I have experimented with two different methods to achieve typing for a custom theme in a React Native project using TypeScript and Expo. I created a declaration ts file and included it in my tsconfig. Below is an overview of my setup, and I'm hopeful that someone who has encountered similar challenges can provide guidance on resolving this issue.

In my themes folder, I have various files which I export and then import into an index theme file as follows:

themes/
  colors
  sizes
  spacing
  index

The index file imports from the aforementioned theme files:

import { DefaultTheme } from "styled-components/native";
import { colors } from "./colors";
import { sizes } from "./sizes";
import { spacing, lineHeights } from "./spacing";

const theme: DefaultTheme = {
  colors,
  sizes,
  spacing,
  lineHeights,
};

export default theme;

Furthermore, I attempted two approaches in creating my declaration file – one involving manual addition of all props and the other utilizing 'typeof'.

types/theme.d.ts

import {} from "styled-components";
import theme from "../themes";

declare module "styled-components" {
  type Theme = typeof theme;
  export interface DefaultTheme extends Theme {}
}

// Manually adding the props.
// import { DefaultTheme } from "styled-components/native";

// declare module "styled-components" {
//   export interface DefaultTheme {
//     bg: {
//       primary: string;
//       secondary: string;
//     };
//     sizes: stringp[];
//     lineHeights: {
//       title: string;
//       copy: string;
//     };
//     spacing: string[];
//   }
// }

tsconfig.json

{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true,
    "baseUrl": ".",
    "paths": {
      "*": ["types/*"]
    },
  },
  "include": ["./src", "./types"],
  "exclude": [
    "node_modules",
    "**/*.test.ts",
    "**/*.test.tsx",
  ]
}

Finally, here is how I am implementing this in my app's tsx file:

App.tsx

import React from "react";
import styled, { ThemeProvider } from "styled-components/native";
import { Text, StatusBar } from "react-native";
import theme from "./src/themes";

export default function App() {
  return (
    <ThemeProvider theme={theme}>
        <Container>
          <Text>some text</Text>
          <StatusBar />
        </Container>
    </ThemeProvider>
  );
}

const Container = styled.View`
  flex: 1;
  background-color: ${({ theme }) => theme.colors.bg.primary};
  align-items: center;
  justify-content: center;
`;

Answer №1

Avoid defining DefaultTheme in the themes/index.ts file as it is already being utilized and serves as an empty object.

Revise your themes/index.ts with the following code:

import { colors } from "./colors";
import { sizes } from "./sizes";
import { spacing, lineHeights } from "./spacing";

const theme = {
  colors,
  sizes,
  spacing,
  lineHeights,
};

export default theme;

Update your types/theme.d.ts as follows:

import "styled-components"
import theme from "./src/themes";

type ThemeInterface = typeof theme

declare module "styled-components" {
    // eslint-disable-next-line @typescript-eslint/no-empty-interface (this is only necessary if you ur eslint complains. Since it should be and Interface and not a Type.) 
    interface DefaultTheme extends ThemeInterface {}
}

By making these adjustments, everything should be in order.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Styling various versions of a <button> using Styled Components

In my app, I have a basic colored button that needs to change its color depending on the UI state: const StyledButton = styled.button` & { border: 0; color: white; cursor: pointer; } &:hover { background-color: ${(props) => ...

Next.js Project Encounters Compilation Error Due to Tailwind CSS Custom Class

I am currently working on a Next.js project and incorporating Tailwind CSS. Unfortunately, I have come across a compilation error that I am struggling to resolve. The error specifically pertains to a custom utility class that I defined in my theme.css file ...

Unable to set up Typescript: The package v1.2.3 cannot meet the peerDependency requirements of its siblings

While attempting to set up Typescript for compiling my Angular2 app, I encountered an error message stating "The package [email protected] does not meet the peerDependencies requirements of its siblings." ...

Using `rootDirs` in a monorepo setting results in unnecessary subfolders like `src` being generated in the `outDir`

I am in the process of planning a monorepo TypeScript project structured as follows: / (root) +--backend/ | +-src/ | \-tsconfig.json +--shared/ | \-src/ \--frontend/ \-src/ The tsconfig.json file looks like this: { "compil ...

Tips on obtaining checkbox values other than "true"

Having trouble retrieving the values of selected checkboxes instead of displaying "Custom Category"? I've attempted to access the values and attributes with no success. I'm aiming to display the values of the selected checkbox. app.component.ht ...

A guide on changing state in React Native

Currently, I am in the process of developing a lightweight project with React Native, and I have come across some challenges that I am finding difficult to overcome. :( On one of the pages in my project, I have included a pair of buttons - one labeled Yes ...

Inject a DOM event into a personalized form validator within an Angular application

I'm currently working on validating a form using the reactive approach. I've implemented a file input to allow users to upload files, with custom validation conditions in place. However, I'm encountering an issue where the validator only rec ...

Unable to access injector in Angular 2

In my application, I have a service called DrawingDataService which contains an array of data and various tools to draw this data. To ensure that DrawingDataService acts as a singleton across all tools, I included it in the providers list of the AppModule: ...

Differentiating AWS API errors in TypeScript: A guide

How can I write different handlers in TypeScript for ThrottlingException and ExecutionLimitExceeded when starting a StepFunction execution? new StepFunction.startExecution({}, (err, data) => { if (err) { // Need to identify ThrottlingExcepti ...

Executing jasmine tests in Visual Studio Code - a step by step guide

After setting up visual studio code with jasmine and typescript installed, I have created a spec file named TestSpec.ts. describe("Testing", () =>{ it("should pass", () =>{ let msg = "Welcome to TypeScript"; //I want to print the msg firs ...

Discovering the 3D coordinates of a point that is perpendicular to the midpoint of a line

(I am working with Javascript/Typescript and Three.js) Given two vectors, let's say {x:1, y:3, z:5} and {x:7, y:8, z:10}, I have a direct straight line connecting them. At the midpoint of this line, envision a disc with a radius of 1 that is perpend ...

Using the Ajax method from a separate class in TypeScript: A step-by-step guide

Recently, I started learning about typescript and ajax. One of the challenges I encountered was while creating a method in typescript for making ajax calls that can be used across classes: myFunc(value: string): JQueryPromise<any> { var dfd = $. ...

Ways to implement logging in an NPM package without the need for a specific logging library

Currently, I am in the process of developing a company npm package using TypeScript and transferring existing code to it. Within the existing code, there are instances of console.log, console.warn, and console.error statements, as shown below: try { c ...

Implementing tailwindcss styles in a typescript interface with reactjs

In my code, I have a file named types.ts that defines an interface called CustomCardProps. I pass this interface to the CustomCard component within the home.tsx file. Additionally, I have a folder named constant with an index.ts file where I store values o ...

Troubleshooting problem with Angular2's Json.parse(--) functionality

Here is the issue related to "JSON.parse(--)" that you need to address: ERROR in E:/Arkin_Angular_Material_latestCode/arkin-layout/src/app/core/service/ http.service.ts (62,53): Argument of type 'void | any[]' is not assignable to parame ...

Error encountered during React Native iOS build - review the render method of the specified class

Recently, I embarked on a journey to learn React Native iOS by following a tutorial from raywenderlich. The versions I am currently using are: react-native-cli: 2.0.1 react-native: 0.60.5 While working on the Adding Navigation Section, I encountered the ...

Display the React component following a redirect in a Next.js application that utilizes server-side rendering

Just starting out with next.js and encountering a problem that I can't seem to solve. I have some static links that are redirecting to search.tsx under the pages folder. Current behavior: When clicking on any of the links, it waits for the API respo ...

The Problem of Unspecified Return Type in Vue 3 Functions Using Typescript

Here is the code snippet I am working with: <template> <div> <ul v-if="list.length !== 0"> {{ list }} </ul> </div> </template> < ...

Undefined output in Typescript recursion function

When working with the recursion function in TypeScript/JavaScript, I have encountered a tricky situation involving the 'this' context. Even though I attempted to use arrow functions to avoid context changes, I found that it still did not work as ...

Using Angular to bind the ngModel to a variable's object property

In my application, I am working with a user object that looks like this: let user = {name: "John", dob:"1995-10-15", metadata: {}} The metadata property of the user object is initially empty. I want to add a new property to the metadata object based on u ...