Using Typescript to retrieve a property by its name using a string as a generic type

I messed up the title, not sure the exact term for what I am trying to achieve. Type constraints are a bit confusing to me right now as I'm learning them in both F# and Typescript at the same time.

I have a variable called interface state that contains lists of all the necessary data types for the page

interface state{
    clients: clients[]
    appointments: appointments[]
    ...
}

const ApplicationState : state = {...}

I need a generic function that can retrieve a specific client, appointment, or any other data by its id.

For example:

getData('clients', 2)

To start, I defined a type with permitted properties (if there's a better way to do this, please let me know).

type entity = "clients" | "appointments"

But would it then be possible to access the property of ApplicationState?

So, could the getData function look something like this?

const getData = (foo: entity, id: number) => {
    ApplicationState.magicallyGetPropertyByName.filter(entity => entity.id = foo.id)
}

Is it achievable while still maintaining type inference?

Appreciate your help

Answer №1

The primary issue at hand is the inability to use filter on a union type like in the following example:


type Clients = {
  tag: 'Clients'
  id: number
}

type Appointments = {
  tag: 'Appointments'
  id: number
}

declare const test: Clients[] | Appointments[]

test.filter(elem => elem)

For more information, refer to issues/7294 and issues/13097

However, there is a workaround available:

type Clients = {
  tag: 'Clients'
  id: number
}

type Appointments = {
  tag: 'Appointments'
  id: number
}

type State = {
  clients: Clients[]
  appointments: Appointments[]
}

type Entity = keyof State;

declare const ApplicationState: State

const withState = <
  S extends Record<string, { id: number }[]>
>(state: S) =>
  <E extends keyof S>(prop: E, id: number) =>
    state[prop].filter(entity => entity.id === id)

const getData = withState(ApplicationState);

getData('clients', 2)

Playground It's worth noting that I defined State as a type instead of an interface because interfaces are not indexed by default. Reverting it back to an interface will result in an error when using withState.

In actuality, you don't need precise types for clients and appointments; you just need to ensure they share a common property like id.

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

I am currently working on configuring a webhook utilizing the Stripe platform with NextJS version 13.2.3

Upon successfully checking out my cart using the built-in Stripe page, I am redirected to the successUrl route. During this process, my local test webhook is triggered as expected. However, I encountered some errors when attempting to verify that the reque ...

Encountering issues with Typescript when providing parameters for res.status().json()

I've recently started using Typescript and I'm still in the learning process by converting some existing JS code to TS. In my code: res.status(200).json({ user: data.user }) I encountered a red squiggly underline under user:data.user ...

Moment-Timezone defaults to the locale settings after the global Moment locale has been established

I am currently developing an application using Typescript that requires features from both Moment.js and moment-timezone. To localize the date and timestamps within the application, I have set moment's locale in the main app.ts file to match the langu ...

What could be the reason for the absence of a TypeScript error in this situation?

Why is it that the code below (inside an arbitrary Class) does not show a TypeScript error in VSCode as expected? protected someMethod (someArg?: boolean) { this.doSomething(someArg) } protected doSomething (mustBePassedBoolean: boolean) { /* ... * ...

Top method for allowing non-component functions to update Redux state without the need to pass store.dispatch() as a parameter

As I work on my first ReactJS/redux project, I find myself in need of some assistance. I've developed a generic apiFetch<T>(method, params) : Promise<T> function located in api/apiClient.ts. (Although not a React component, it is indirect ...

Angular Tutorial: Modifying the CSS transform property of HTML elements within a component directly

Currently, I'm in the process of developing an analog clock for a project using Angular. My challenge is figuring out how to dynamically update the sec/min/hour handlers on the clock based on the current time by manipulating the style.transform prope ...

Angular module with customizable configurations

I am interested in developing a customizable Angular 9 module with IVY and AOT enabled. In the latest version of Angular, IVY and AOT are automatically activated: npx @angular/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed8 ...

The redirection code is not being executed when calling .pipe() before .subscribe()

My AuthService has the following methods: signUp = (data: SignUp): Observable<AuthResponseData> => { const endpoint = `${env.authBaseUrl}:signUp?key=${env.firebaseKey}`; return this._signInOrSignUp(endpoint, data); }; signIn = (data: SignIn): ...

How should dynamic route pages be properly managed in NextJS?

Working on my first project using NextJS, I'm curious about the proper approach to managing dynamic routing. I've set up a http://localhost:3000/trips route that shows a page with a list of cards representing different "trips": https://i.stack. ...

Some elements that fit the criteria of 'number | function' are not callable at all

Consider a basic function like this: export const sum = (num?: number) => { const adder = (n: number) => { if (!n) { return num; } num = (num && num + n) || n; return adder; }; return a ...

Creating Typescript libraries with bidirectional peer dependencies: A complete guide

One of my libraries is responsible for handling requests, while the other takes care of logging. Both libraries need configuration input from the client, and they are always used together. The request library makes calls to the logging library in various ...

Setting up @cypress/code-coverage with Angular and TypeScript: A comprehensive guide

When following the instructions in Cypress documentation for @cypress/code-coverage, it recommends using the following code... // cypress/support/e2e.js import '@cypress/code-coverage/support' ...as well as... // cypress.config.ts import { defin ...

Angular 8 encountered a 404 (Not Found) error when trying to POST to http://localhost:4200/assets/data/students.json

I'm currently working on a project that involves fetching array data through HTTP and should also allow for the addition of new arrays using HTTP. However, every time I attempt to post a new array, I encounter the following error: POST http://local ...

Guide on navigating to a specific page with ngx-bootstrap pagination

Is there a way to navigate to a specific page using ngx-bootstrap pagination by entering the page number into an input field? Check out this code snippet: ***Template:*** <div class="row"> <div class="col-xs-12 col-12"> ...

When using tsdx with React, null values can prevent proper usage of hooks

Recently, I attempted to develop a React TypeScript component using tsdx for compilation and encountered a roadblock while debugging. The package appears to be successfully published and installed without any errors. However, when trying to use it, I consi ...

Yelp API call resulting in an 'undefined' response

When attempting to make an API call using the yelp-fusion, I noticed that the logged result is showing as undefined. It seems like this issue might be related to promises or async functions. It's important for me to maintain this within a function sin ...

Issues with updating values in Angular form controls are not being resolved even with the use of [formControl].valueChanges

[formControl].valueChanges is not triggering .html <span>Test</span> <input type="number" [formControl]="testForm"> .ts testData: EventEmitter<any> = new EventEmitter<any>(); testForm: FromCo ...

How can Node / Javascript import various modules depending on the intended platform?

Is there a way to specify which modules my app should import based on the target platform in TypeScript? I am interested in importing different implementations of the same interface for a browser and for Node.js. In C++, we have something like: #ifdef wi ...

Combining Closure Compiler with Typescript

My objective is to leverage Typescript along with Closure Compile (advanced compilation) to target ES5 and then minify the resulting output. Is it mandatory for me to replace tsc with tsickle? I find that tsickle does not provide support for all options a ...

What is causing the error TS2339 to be thrown when attempting to access a class property in this TypeScript illustration: "Property 'text' does not exist on type 'T'"?

Could someone provide insight into why attempting to access a class property in this scenario is resulting in the error message error TS2339: Property 'text' does not exist on type 'T'. Here is the TypeScript code: class Base { rea ...