Utilizing generics in conjunction with zustand's create function

In my Zustand store, I am storing items of type GridRow<T>. These items represent selected rows in a main grid, with the use of generics to specify the data used in the grid.

I am facing a challenge on how to pass the generic parameter to the store's create method. It is not feasible to wrap it in another function as it would result in creating a new store every time.

interface MainGridState<T> {
  selectedRows: Array<GridRow<T>>
}

const initialState = {
  selectedRows: []
}

// The issue arises here as T is undefined and there is no way to declare it explicitly
const useMainGridStore = create<MainGridState<T>>()(set => ({
  ...initialState,
}))

export const useMainGridSelectedRows = <T>(): Array<GridRow<T>> =>
  useMainGridStore<T>(state => state.selectedRows)

Answer №1

Check out this code snippet:

interface MainGridState<T> {
  selectedRows: Array<GridRow<T>>
}

export type UseDataReturn<T> = {
  data: MainGridState<T>;
};

const initialState: UseDataReturn<{}>["data"] = {
  selectedRows: []
};

export const useMainGridSelectedRows = create<UseDataReturn<{}>>((set) => ({
  data: initialState,
}));

export const useMainGridStore = useMainGridSelectedRows as {
  <T>(): UseDataReturn<T>;
  <T, U>(selector: (s: UseDataReturn<T>) => U): U;
};

// example of how to use it
function Test() {

  // Provide the desired type instead of 'string'

  const dataExample = useMainGridStore<GridRow<string>[]>().data;

  const stateExample = useMainGridStore<string, GridRow<string>[]>(state => state.data.selectedRows)
}

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

TypeScript conditional return type: effective for single condition but not for multiple conditions

In my code, I have implemented a factory function that generates shapes based on a discriminated union of shape arguments. Here is an example: interface CircleArgs { type: "circle", radius: number }; interface SquareArgs { type: "square" ...

typescript unable to use module as variable in import statement

Having trouble importing a variable from another file in TypeScript and assigning an alias name. I keep getting an error saying the alias name is not defined. For example: import { headerItems as TestHeader } from './headers'; Typescript versi ...

Could anyone provide an explanation for the statement "What does '[P in keyof O]: O[P];' signify?"

As a new Typescript user looking to build a passport strategy, I came across a line of code that has me completely baffled. The snippet is as follows: here. The type StrategyCreated<T, O = T & StrategyCreatedStatic> = { [P in keyof O]: O[P]; ...

What is the best way to generate a switch statement based on an enum type that will automatically include a case for each enum member?

While Visual Studio Professional has this feature, I am unsure how to achieve it in VS Code. Take for instance the following Colors enum: enum Colors { Red, Blue, When writing a switch statement like this: function getColor(colors: Colors) { swi ...

Issue with inconsistency in TypeScript when updating image sources within Promise.all

Currently, in my SPFx webpart using React/TypeScript, I am facing a challenge with replacing the source of some images. The initial source needs to be fetched first via another Microsoft Graph API call before being replaced. My approach involves fetching ...

What is the correct way to handle Vue props that include a dash in their name?

I am currently working on a project using Vue. Following the guidelines of eslint, I am restricted from naming props in camel case. If I try to do so, it triggers a warning saying Attribute ':clientId' must be hyphenated. eslint vue/attribute-hyp ...

You cannot use objects as valid children in React layout components

I encountered an issue with my layout: Unhandled Runtime Error Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead. The code in my DashboardLayout file (dashboardLa ...

Guide on categorizing MUI icon types

My current code snippet is as follows: type MenuItem = { key: string; order: number; text: string; icon: typeof SvgIcon; }; However, when I attempt to use it in my JSX like this: <List> {MENU.map((menuItem: MenuItem) => ( ...

The issue of not displaying the Favicon in Next.js is a common problem

I am currently using Next.js version 13.4.7 with the App directory and I am facing an issue with displaying the favicon. Even though the favicon image is located in the public folder and in jpg format, it is not being displayed on the webpage. However, w ...

Numerous subscribers utilize Angular 2 for handling HTTP requests

Working with data returned from an http post request in both a service and a page in Angular 2 can be tricky. The challenge arises when calling the service function this.Auth.login(), which initiates the http post request. Upon receiving the data from the ...

What is the reason behind Typescript's discomfort with utilizing a basic object as an interface containing exclusively optional properties?

Trying to create a mock for uirouter's StateService has been a bit challenging for me. This is what I have attempted: beforeEach(() => { stateService = jasmine.createSpyObj('StateService', ['go']) as StateService; } ... it(& ...

Unable to showcase a dynamic image using [style.background-image] in Angular 7

I am encountering an issue in my Angular application where I am unable to load background images dynamically from my backend. Displaying regular pictures is not a problem for me. However, the background images are not loading and I do not receive any err ...

What is the best way to connect Classes and Objects in Angular5?

Picture a study tool with flashcards and different categories. Each category has a title, while each card contains content, is linked to only one category, and is also connected to another card. How can I establish these connections in Angular 5 and Types ...

Dealing with missing image sources in Angular 6 by catching errors and attempting to reset the source

When a user adds a blob to my list, sometimes the newly added image is still uploading when the list is refreshed. In this case, I catch the error and see the function starting at the right time: <img src="https://MyUrl/thumbnails/{{ blob.name }}" widt ...

Error in Typescript: The argument 'T' cannot be assigned to the parameter of type 'number'

Could someone help me diagnose the typescript error in this code snippet? public sortList<T>(data: T[], key: string, action: boolean): Observable<T[]> { const outputData: T[] = data.sort((a, b) => { if (isNaN(a) && isNaN(b)) ...

Is it possible to specify the data type of form control values when using the Angular Reactive form builder?

Is it possible to use typed reactive forms with Angular form builder? I want to set the TValue on the form control to ensure we have the correct type. For example: public myForm= this.fb.group({ name: ['', [Validators.required, Validators.max ...

Tips for updating parameters that are defined in a controller within a promise

Currently, I am developing a single page application using Angular and TypeScript. I am facing an issue with updating the parameter value (_isShowFirst) of the controller inside a promise function. It seems like nothing is recognized within the promise blo ...

Exploring Typescript: Combining types (rather than intersecting them)

Let's analyze the scenario below type MergeFn = <K1 extends string, V1, K2 extends string, V2>( k1: K1, v1: V1, k2: K2, v2: V2 ) => ??? let mergeFn: MergeFn // actual implementation doesn't matter for this question What should b ...

Error encountered in React TypeScript: Expected symbol '>' was not found during parsing

While transitioning from JavaScript to TypeScript, I encountered an error in my modified code: Error on Line 26:8: Parsing error: '>' expected import React from "react"; import { Route, Redirect, RouteProps } from "react-router ...

What function does the ng-template serve when encapsulated within an ng-select component?

Upon observing various instances of ng-select, I've noticed that it often involves wrapping a ng-template, as exemplified below: <ng-select [items]="cities" [(ngModel)]="selectedCity" bindLabel="name" bindV ...