Typescript: searching for a specific type within an array of objects

The title may be a bit unclear, but I'm struggling to find a better way to explain it.
I have a predefined set of classes from a third-party library that I cannot modify. The specific content of these classes is not relevant, as it's just for illustrating the situation

class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}

Now, I need to create a function that will work with these classes

const doSomething = <T extends Parent>(someClass: T, options: SomeOptions<T>) => {}


doSomeThing(new Child1(), {foo: 'bar'});
doSomeThing(new Child2(), {id: 1});

Depending on the class provided, different sets of options are required. I want to define interfaces for these options to enable autocompletion. Ideally, it would look like this

interface SomeOptions {
    Child1: {foo: string},
    Child2: {id: number},
}

However, using classes as an index type is not possible. So, I'm thinking of structuring it like this instead

type SomeOptions = [
    {class: Child1, options: {foo: string}},
    {class: Child2, options: {id: number}},
]

Given this setup, how can I retrieve the correct options based on a class?

const doSomething = <T extends Parent>(someClass: T, options: FindMeTheCorrectOption<T>) => {}

My objective is as follows

doSomeThing(new Child1(), {foo: 'bar'}); // okay
doSomeThing(new Child2(), {id: 1}); // okay

doSomeThing(new Child2(), {foo: 1}); // TypeScript error, foo must be a string

Answer №1

After experimenting in the playground, I have obtained some interesting results. By using someClass as the Parent, we can allow input to be any class that extends from Parent. The options parameter will only accept the correct type of SomeOptions.

interface SomeOptions {
  Child1: { foo: string };
  Child2: { id: number };
}
class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}
const doSomeThing = <T extends keyof SomeOptions>(
  someClass: Parent,
  options: SomeOptions[T]
) => {};
doSomeThing(new Child1(), {foo: 'bar'}); // this is valid
doSomeThing(new Child2(), {id: 1}); // this is also valid

doSomeThing(new Child2(), {foo: 1}); // TypeScript error - foo must be a string

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 method to merge min and max validation errors when using React Hook Form?

<input {...register("subject", { maxLength: 50, minLength: 2, required: true, })} disabled={isLoading} id="subject" autoComplete=&q ...

"Error encountered: 'Callable function cannot be invoked on Mongoose model

In my Nest JS service, the code structure is as follows: import { Injectable } from '@nestjs/common'; import { Model } from 'mongoose'; import { InjectModel } from '@nestjs/mongoose'; import { Collection } from './inter ...

Using keyof on an indexed property within a generic type in Typescript does not effectively limit the available options

Imagine having an interface structure like this: export interface IHasIO { inputs: { [key: string]: string }, outputs: { [key: string]: string } } The goal is to develop a function that adheres to this interface as a generic type and ensur ...

Why is the table not sorting when I apply filters?

I am encountering an issue where the data filters and table sorting are not working together. When I apply filters, the sorting functionality stops working. The filters work fine independently, but once applied, they interfere with the sorting feature. Any ...

The type 'RefObject<HTMLDivElement>' cannot be matched with type 'RefObject<HTMLInputElement>' in this context

Encountered an error message: Issue with assigning types: Type '{ placeholder: string | undefined; autoComplete: string | undefined; "data-testid": string | undefined; onChange?: ChangeEventHandler<HTMLInputElement | HTMLTextAreaElement&g ...

What is the process for adjusting the color of axes in vue-chartjs?

Seeking help on how to adjust the color of the axis in my graph. Has anyone encountered a similar issue before? The chart I'm working with resembles the one shown in the image. Not sure if this issue is related to it being a time graph. Below is the V ...

Ways to transfer certain characteristics of an Observable to a different Observable by leveraging RxJS operators

I am working with two Observables, employee$ and personalInformation$. The personalInformation$ Observable is a subset of employee$ and I need to map the matching properties from employee$ to personalInformation$. Although both observables have many more f ...

Ways to mandate a field to only be of type object in TypeScript

I need to design a type that includes one mandatory property and allows for any additional properties. For instance, I require all objects to have an _id property of type string. {_id: "123"} // This will meet the criteria {a: 1} // This will not work as i ...

Angular testing with Jasmine and TypeScript

I've been attempting to create some Angular Controller tests for my App using TypeScript for a few days now, but haven't had any success. Let me start by saying that this is my first time writing tests in Jasmine. My issue is that I'm having ...

Associate union with interface attributes

Can a union type be transformed into an interface in Typescript? My Desired Outcome If we have a union type A: type A = 'one' | 'two' | 'three'; I want to convert it to interface B: interface B { one: boolean; two ...

regex execution and testing exhibiting inconsistent behavior

The regex I am using has some named groups and it seems to match perfectly fine when tested in isolation, but for some reason, it does not work as expected within my running application environment. Below is the regex code that works everywhere except in ...

Jest is unable to handle ESM local imports during resolution

I am encountering an issue with my Typescript project that contains two files, a.ts and b.ts. In a.ts, I have imported b.ts using the following syntax: import * from "./b.js" While this setup works smoothly with Typescript, Jest (using ts-jest) ...

Keeping track of important dates is ineffective using the calendar

I am facing an issue with developing a calendar that marks events on the correct dates. I am receiving the dates in the following format in PHP [ { "status": "OK", "statusCode": 200, "statusMensagem": & ...

Is there a way to assign values of object properties to the corresponding object in TypeScript?

I'm looking for a solution in TypeScript where I can map values of object keys to the same object, and have IntelliSense work correctly. Here's an example that illustrates what I need: const obj = getByName([ { __name: 'foo', baz: &ap ...

Utilize ngClass for every individual section

I have completed the implementation of all UI components, which are visually appealing. https://i.sstatic.net/hxJQr.png Here is the data structure I am using: public filters = [ { tag: 'Year', label: 'ye ...

Sweetalert seems to have hit a roadblock and is not functioning properly. An error has been detected in its TS file

Currently, I am responsible for maintaining an application that utilizes Angular 7.0.7 and Node 10.20.1. Everything was running smoothly until yesterday when my PC unexpectedly restarted. Upon trying to run ng serve, I encountered the following error: E ...

Dynamically attach rows to a table in Angular by triggering a TypeScript method with a button click

I need help creating a button that will add rows to a table dynamically when pressed. However, I am encountering an error when trying to call the function in TypeScript (save_row()). How can I successfully call the function in TypeScript and dynamically a ...

Guide on incorporating Kendo UI typings into a TypeScript module

Currently, I am working with Kendo UI for React and TypeScript. My goal is to import the Kendo UI typings for TypeScript using a "typeof import". Following the guidance provided at https://docs.telerik.com/kendo-ui/third-party/typescript, I successfully i ...

JavaScript's Array.map function failing to return a value

Here is a snippet of code from an api endpoint in nextJS that retrieves the corresponding authors for a given array of posts. Each post in the array contains an "authorId" key. The initial approach did not yield the expected results: const users = posts.ma ...