Tips for resolving the TypeScript error of Object potentially being 'undefined' when passing theme to a function

I am looking to create a custom component in React Native that will allow me to have different sizes for buttons using react-native-elements. To achieve this, I created a custom component with a property called size, which dynamically accesses specific button sizes and their respective styles from the theme object. Everything is working as expected, but I keep getting the TypeScript error

TS2532: Object is possibly 'undefined'.
every time I try to access the sizes object within the theme using bracket notation.

Custom Button Component

import React, { useContext } from 'react';
import { Button, FullTheme, ThemeContext } from 'react-native-elements';

export type Props = Button['props'];
export type Theme = Partial<FullTheme>;

const styles = {
  button: (theme: Partial<FullTheme>, size: string) => ({
    padding: theme?.Button?.sizes[size]?.padding, // issue here
  }),
  title: (theme: Partial<FullTheme>, size: string) => ({
    fontSize: theme?.Button?.sizes[size]?.fontSize, // issue here
    lineHeight: theme?.Button?.sizes[size]?.lineHeight, // issue here
    fontFamily: theme?.Button?.font?.fontFamily,
  }),
};

function ButtonElement(props: Props): JSX.Element {
  const {
    size = 'medium',
    children,
    ...rest
  } = props;
  const { theme } = useContext(ThemeContext);

  return (
    <Button
      titleStyle={styles.title(theme, size)}
      buttonStyle={styles.button(theme, size)}
      {...rest}
    >
      {children}
    </Button>
  );
}

theme.ts

export const theme = {
  Button: {
    font: {
      fontFamily: 'inter-display-bold',
    },
    sizes: {
      small: {
        fontSize: 14,
        padding: 10,
        lineHeight: 20,
      },
      medium: {
        fontSize: 18,
        padding: 14,
        lineHeight: 24,
      },
      large: {
        fontSize: 20,
        padding: 18,
        lineHeight: 24,
      },
    },
  },
}

// react-native-elements.d.ts -> Extending the default theme to manage button sizes 
import 'react-native-elements';
import { StyleProp, TextStyle } from 'react-native';

export type Sizes = {[index: string]: TextStyle};
export type Size = 'small' | 'medium' | 'large';

declare module 'react-native-elements' {
  export interface ButtonProps {
    font?: TextStyle;
    sizes?: Sizes;
    size?: Size;
  }

  export interface FullTheme {
    Button: Partial<ButtonProps>;
  }
}

Passing the theme Object to the Components Tree

// pass theme to the component tree
import { theme } from '@common/styles/theme';

export default function App(): JSX.Element | null {
  return (
    <ThemeProvider theme={theme}>
      <SafeAreaProvider>
        <Navigation />
        <StatusBar />
      </SafeAreaProvider>
    </ThemeProvider>
  );
}

What I Have Attempted

  • I've tried using the ? operator as suggested in this answer.
  • I have also explored suggestions mentioned in this post, using if statements to ensure that theme is not undefined.

Answer №1

TS2532: Object is possibly 'undefined'
pops up whenever I attempt to access the sizes object within the theme using bracket notation.

This situation is intriguing because the optional chaining operator is not being utilized after the sizes field.

You have a couple of choices:

  1. If you are certain that the sizes field will always be present and not null or undefined, you can make use of TypeScript's non-null assertion type-operator (a static typing feature).

  2. Alternatively, try accessing the size with

    theme?.Button?.sizes?[size]?.fontSize
    (a dynamic runtime approach).

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

What is the best way to create a dynamic URL linking to an external site in Angular 5?

When attempting to create a link like this: <a [href]="getUrl()">click me</a> getUrl() { return this.domSanitizer.bypassSecurityTrustUrl('http://sampleUrl.com'); } The link is not clickable. When hovering over the ...

Tips on preventing the duplication of component instances in your project

Check out the plunker link to see that the child component "Loader" is being loaded multiple times every time the button is clicked. How can I prevent creating multiple instances of the same component? I want the new instance to replace the existing one wh ...

The type 'HTMLDivElement | null' cannot be assigned to the type 'HTMLDivElement' in this context

Struggling with a scroll function to maintain position while scrolling up or down - encountering an error: Error: Type 'HTMLDivElement | null' is not assignable to type 'HTMLDivElement'. Type 'null' is not assignable to type & ...

Guide to accessing Node Modules in TypeScript within an ASP.Net Core Web Application

After successfully installing the npm library xrm-mock into my ASP.Net Core Web Application, I noticed that it appears both in the npm folder and the node_module folder on the disk: https://i.sstatic.net/rAbcQ.jpg The issue arises when a file located at t ...

Retrieve the essential information needed from the REST API

I have a test wordpress blog set up. To enhance the functionality, I developed an angular app that utilizes the wordpress rest api. The app makes a call to an endpoint to retrieve categories. However, the JSON response contains unnecessary data for my appl ...

How can I properly specify the type of a function for a complex object with index signatures in TypeScript?

Problem with Retrieving Specific Data from Mixed Object I'm encountering an issue with a function that is supposed to retrieve a specific piece of data within an object. The object contains a combination of known indexes and index signatures, which s ...

Converting a JSON object into a different format using TypeScript

Looking for advice on how to efficiently convert JSON data into a specific format without hardcoding any values like "root" or "Amount". I want to create a reusable function that can be used in various scenarios. Currently, I am working with TypeScript and ...

Tips for testing the logic of rxjs debounceTime in an Angular project?

After diving headfirst into coding with RxJs without much prior knowledge, I found myself copying and pasting code snippets, tweaking them to fit my needs, only to hit roadblocks when trying to test the code... Let me share the entire component for contex ...

Angular 6 and D3 version 5.5 are causing an issue with the undefined `<variable>`

At the moment, I am attempting to create a Hierarchical Bar Chart in my Angular App using D3. When I click on a bar, I expect my function to recursively reshape the chart. The initial call works fine, but once I click on a bar, the variables become undefin ...

What is the best way to arrange this script?

I am currently working on a Javascript script that automatically scrolls down and loads a new URL when it reaches the bottom of the page. However, I would like to add a delay of 30 seconds before the new URL is loaded. Although I am relatively new to Java ...

Angular configuration for intercepting HTTP errors with RxJS Replay Subject

I am currently facing an issue where I am trying to retrieve the value of an error and show a customized error message using an HTML element. In order to manage the state of the error, I am utilizing a Replay Subject in my Interceptor. The interceptor is c ...

Utilize SCSS values within TypeScript by applying them on a class level

let changeClassDisplay = document.getElementsByClassName('sidebar'); for (var i = 0; i < changeClassDisplay.length; i += 1) { changeClassDisplay[i].style.display = 'block'; } I encountered an issue with this code whe ...

When trying to convert JavaScript to TypeScript, an error occurs stating that the module cannot

Currently in the process of migrating my project from JavaScript to TypeScript, focusing on the server-side implementation. Encountering an error which is detailed below. internal/modules/cjs/loader.js:883 throw err; ^ Error: Cannot find module &apos ...

The call cannot match any overload due to error TS2769

I've been working on a small Angular application: The file movie.service.ts is structured like this import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { environment } from '. ...

The dropdown cannot be disabled because it is being passed as an input parameter

We are currently utilizing PrimeNG along with Angular 15. Scenarios: According to the requirements, we need the ability to disable the PrimeNG dropdown control based on a selection. Problem: The disabled property of <p.dropdown> is not functioning ...

Creating a customized control in Nativescript: Enhancing Dependency Properties

I am currently developing a custom component that consists of a list of buttons. Whenever a user clicks on a button, I modify its CSS class and then I want to add it to a custom property called "selectedItems" in order to retrieve it in my ViewModel. How ...

Downloading files (PDF, JPG, PNG) instead of automatically opening in a new tab

Is there a way to automatically download PDF and JPG files instead of opening them in a new tab like .docx files? Currently, when clicking on a PDF or JPG link, it opens in a new tab rather than downloading the file. The desired behavior is for these files ...

What are the best methods for implementing runtime type checking in JavaScript?

Utilizing either TypeScript or Facebook's Flow (type), I am empowered to statically assign types to variables like this: function add (x: integer, y: integer) { ... } Both TypeScript and Flow are able to identify and prevent incorrect invocations su ...

Mastering Angular Apollo Error Resolution Methods

Hey everyone, I'm facing a problem with apollo-angular and apollo-link-error that I just can't seem to figure out. I've experimented with different approaches but have had no luck catching errors on the client-side of my angular web app. Bel ...

Error in hook order occurs when rendering various components

A discrepancy was encountered in React when attempting to render different components Warning: React has detected a change in the order of Hooks called by GenericDialog. This can result in bugs and errors if left unresolved. Previous render Next ren ...