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 are the steps for importing a file into a React app that is built using Create React App as plain text?

Objectives I aim to showcase code snippets from the project itself for reference. I intend to keep the displayed code up-to-date with its implementation. I prefer not to remove myself from create-react-app This React project, built using create-react-ap ...

Utilizing precise data types for return values in React hooks with Typescript based on argument types

I developed a react hook that resembles the following structure: export const useForm = <T>(values: T) => { const [formData, setFormData] = useState<FormFieldData<T>>({}); useEffect(() => { const fields = {}; for (const ...

Encountering a Typescript error with Next-Auth providers

I've been struggling to integrate Next-Auth with Typescript and an OAuth provider like Auth0. Despite following the documentation, I encountered a problem that persists even after watching numerous tutorials and mimicking their steps verbatim. Below i ...

How to dynamically disable a checkbox in Angular reactive forms depending on the value of another checkbox

I am attempting to deactivate the checkbox based on the value of other checkboxes. Only one of them can be activated at a time. When trying to activate one of the checkboxes, I encounter an issue where the subscribed value is being repeated multiple times ...

Having trouble with Angular 2 not properly sending POST requests?

Having some trouble with a POST request using Angular 2 HTTP? Check out the code snippet below: import { Injectable } from '@angular/core'; import { Http, Response, Headers, RequestOptions } from '@angular/http'; import 'rxjs/add ...

Issue encountered when working with interface and Observable during the http parsing process

Visual Studio File Structure Error app(folder) -->employee-list(folder) -->employee-list.component.html -->employee-list.component.ts -->app.component.html -->app.component.ts -->app.module.ts -->employee.json ...

Only filter the array by its value if the value is specified

Is there a way to apply this filter while only checking each condition if the value is not undefined? For instance, if taxId is undefined, I would like to skip it rather than using it as a filter criterion. this.subAgencies = demoSubAgencies.filter(fun ...

Tips for displaying bar chart labels effectively with ChartJS

I am working on an Angular project and I would like to incorporate a barchart using ChartJS. The data for this chart can vary in size, sometimes being very large. One issue I have encountered is that when the number of data points is large, the labels ove ...

best typescript configuration for node 8 suggested

When configuring TypeScript for use with Node 8, what is the optimal setup? Many tutorials recommend using the following tsconfig.json: { "compilerOptions": { "target": "es6", "module": "commonjs" } } However, it has come to my attention tha ...

Ensuring thoroughness in validation without the use of specific text strings

Implementing the assignment or assertion of never at the end of a function is a strategy commonly used in Typescript to ensure exhaustive checks at compile time. To enable the compiler to recognize this, explicit strings are needed for it to check against ...

Proper utilization of react-hook-form in conjunction with TypeScript and material-ui to display error messages efficiently

Currently, I am using a combination of react-hook-form with typescript and material-ui. My goal is to pass the error message as a helperText to the TextField. I attempted to achieve this by utilizing helperText={errors.email?.message} however, TypeScript ...

The parameters provided in TypeScript do not align with any signature of the call target

In JavaScript, a function can be called with any number of parameters. If a parameter is not passed, it will default to undefined without causing an error. Below is a code snippet for reference: function test(a,b){ if(b){console.log(b)} else{console ...

Creating a project using TypeScript, NodeJs, and mongoose-paginate-v2 seems like an impossible

Having trouble setting up mongoose-paginate-v2 in my current project. I'm facing three errors while trying to compile my code. Any ideas on why this is happening? Many thanks. node_modules/@types/mongoose-paginate-v2/index.d.ts:34:21 - error TS2304: ...

Utilizing aria-role in Material UI's <Icon> component for enhanced accessibility

I've been using Material UI's <Icon /> component and came across a reference in their documentation about being able to use role="img", which is mentioned here: https://material-ui.com/components/icons/#semantic-svg-icons. However ...

I'm having trouble with my code not working for get, set, and post requests. What could be causing this issue and how can I

Here are the TypeScript codes I've written to retrieve product details and delete them. import { Component, OnInit } from '@angular/core'; import {FormGroup,FormBuilder, FormControl, Validators} from "@angular/forms" // other impor ...

Efficiently Parsing FormData in React with TypeScript for Improved Data Formatting

Recently, I've started working with React and Typescript and one of the challenges I'm facing is managing an editable table with default values that can be updated and submitted. The data format for the parameters is crucial as the fields and va ...

What are the properties used in functional components of React?

Seeking guidance on passing React component props to another component: interface IMyComponent { props: Props<any> } const MyComponent: FC = ({ props }) => { } Previously, I attempted to utilize the React.Props type after consulting this que ...

Combining two elements in Angular 2

I am looking to find the intersection of two objects. My goal is to compare these objects and if they have matching values on corresponding keys, then I want to add them to a new object. obj1 = { "Projects": [ "test" ], "Companies": [ "facebook", "google ...

Include a fresh attribute in the Interface

How can I include a boolean property isPhotoSelected: boolean = false; in an API interface that I cannot modify? The current interface looks like this: export interface LibraryItem { id: string; photoURL: string; thumbnailURL: string; fi ...

Issue encountered during mozjpeg installation - unable to locate mozjpeg's cjpeg in the vendor directory due to

During my attempt to set up mozjpeg within a Docker container running NAME="Alpine Linux" ID=alpine VERSION_ID=3.11.7 PRETTY_NAME="Alpine Linux v3.11" HOME_URL="https://alpinelinux.org/" BUG_REPORT_URL="https://bugs.alpin ...