Create a generalized function that retrieves offspring sharing a common interface

Struggling to create a single generic function that can return child interfaces inheriting the same parent interface.

Specifically, looking to implement the getById method:

interface Car { brand: string }
interface Ford extends Car { someUniqueAttribute: string }
interface Ferrari extends Car { someOtherUniqueAttribute: string }

const aFord: Ford = getById<Ford>('1')
const aFerrari: Ferrari = getById<Ferrari>('2')

Tried two approaches:

Using generic:

interface CarRepository {
  getById<C extends Car>(id : string): C
}

class CarRepositoryImpl implements CarRepository {
 public getById<C extends Car> (id: string): C {
   return id === '1'
     ? { brand: 'Ford', someUniqueAttribute: 'foo' }
     : { brand: 'Ferrari', someOtherUniqueAttribute: 'bar' }
  }
}

Encountered the error:

TS2322: Type '{ brand: string; }' is not assignable to type 'C'.   
    '{ brand: string; }' is assignable to the constraint of type 'C', but 'C' could be instantiated with a different subtype of constraint 'Car'

Using method overloads:

interface CarRepository {
  getById(id : string): Ford
  getById(id : string): Ferrari
}

class CarRepositoryImpl implements CarRepository {
 public getById (id: string): Ford | Ferrari {
   return id === '1'
     ? { brand: 'Ford', someUniqueAttribute: 'foo' }
     : { brand: 'Ferrari', someOtherUniqueAttribute: 'bar' }
  }
}

Resulted in the error:

Property 'getById' in type 'CarRepositoryImpl' is not assignable to the same property in base type 'CarRepository'.
  Type '(id: string) => Ford | Ferrari' is not assignable to type '{ (id: string): Ford; (id: string): Ferrari; }'.
    Type 'Ford | Ferrari' is not assignable to type 'Ford'.
      Property 'someUniqueAttribute' is missing in type 'Ferrari' but required in type 'Ford'.(2416)

Even though I comprehend the issue with TypeScript, struggling to find the right implementation. Is there a way to accomplish this in TypeScript?

Answer №1

fetchCar retrieves a Car object from the database, which could be either a Toyota or Honda. Next, create a function called

static isToyota(potentialToyota: any) { /* check for specificAttribute */ }
and do the same for Honda. After fetching the car, determine whether it is a Toyota or Honda.

This approach allows you to query the database without prior knowledge of the type of car you will receive

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

When utilizing the Map.get() method in typescript, it may return undefined, which I am effectively managing in my code

I'm attempting to create a mapping of repeated letters using a hashmap and then find the first non-repeated character in a string. Below is the function I've developed for this task: export const firstNonRepeatedFinder = (aString: string): strin ...

The origin of the Angular img src becomes blurred when invoking a function

I want to dynamically change the image src by calling a function that returns the image path. However, when I attempt to do so using the code below, the image element displays as <img src(unknown)/> component.ts: getMedia(row) { this.sharedData ...

Clicking the button in Angular should trigger a series of functions to be

It seems like I'm struggling with a simple question due to my lack of experience in this area. Any guidance or help would be greatly appreciated. I have a button that should trigger multiple functions when clicked, all defined in the same ts file. Wh ...

Implement the usage of plainToClass within the constructor function

I have a dilemma with my constructor that assigns properties to the instance: class BaseModel { constructor (args = {}) { for (let key in args) { this[key] = args[key] } } } class User extends BaseModel { name: str ...

Update the data and paginator status

In my development project, I have implemented PrimeNG Turbotable with the code <p-table #dt. Based on information from here, using dt.reset() will clear the sort, filter, and paginator settings. However, I am looking for a solution to only reset the pa ...

Unable to clear all checkboxes after deleting

In my application, there are 3 checkboxes along with a master checkbox that allows users to select or deselect all of them at once. Everything works fine with the master checkbox until I delete some rows from the table. After deleting data, I can check th ...

How to identify generic return type in TypeScript

My goal is to develop a core dialog class that can automatically resolve dialog types and return values based on the input provided. I have made progress in implementing this functionality, but I am facing challenges with handling the return values. Each ...

Unable to locate 'reflect-metadata' module within Docker container on Production Server

I encountered an error: module.js:550 throw err; ^ Error: Cannot find module 'reflect-metadata' at Function.Module._resolveFilename (module.js:548:15) at Function.Module._load (module.js:475:25) at Module.require ( ...

The installation of @types/jquery leads to an unnecessary global declaration of $

In my package.json file, I have the following dependencies defined: { "dependencies": { "@types/jquery": "^3.5.5", } } This adds type declarations through @types/jquery/misc.d.ts, including: declare const jQuery: JQue ...

In the domain of React and Typescript, a minimum of '3' arguments is anticipated; nonetheless, the JSX factory 'React.createElement' is only equipped with a maximum of '2' arguments. This incongruity is signaled by the

I am facing an error with this particular component: const TheBarTitle = ( theClass: any, columnTitle: string, onClickAction: any, ) => { return ( <div className={theClass} title="Click to add this ...

Testing useEffect with React hooks, Jest, and Enzyme to add and remove event listeners on a ref

Here is a component I've been working on: export const DeviceModule = (props: Props) => { const [isTooltipVisible, changeTooltipVisibility] = useState(false) const deviceRef = useRef(null) useEffect(() => { if (deviceRef && dev ...

What is the method to define a function that strictly accepts a value of type T only if IsSomething<T> evaluates to true?

In my system, there is a complex generic type called IsUnique<T> that evaluates to either true or false based on the input type T: type IsUnique<T> = (/* ... */) ? true : false; Now I am looking to develop a function that takes an unique value ...

Typescript in React is throwing an error that says you cannot destructure the property 'colored' from the 'boxShadows' object because it is undefined

After downloading the material dashboard react theme from an open source GitHub project, I tried to convert the project into Typescript (React + Typescript). However, I encountered the following error (See Attached Image) https://i.stack.imgur.com/YZKpK.p ...

Typescript implements strict enforcement of partial interfaces

In my application, I am working with JSON data. Here is a simplified example: data { prop1: "abc", prop2: 123, COL_A12: "mydata", COL_A13: "myotherdata", } I am aware that the data will consist of multiple prop1 and prop2 properties. However, CO ...

Ionic: Automatically empty input field upon page rendering

I have an input field on my HTML page below: <ion-input type="text" (input)="getid($event.target.value)" autofocus="true" id="get_ticket_id"></ion-input> I would like this input field to be cleared eve ...

Encountering an issue during the registration of reducers with ActionReducerMap: "does not match the type 'ActionReducerMap<AppState, Action>'"

Here is a simplified version of my Angular 5 application. I have a reducer that needs to be registered in the root module. The problem arises in LINE A where I encounter the following error: ERROR in src/app/store/app.reducers.ts(7,14): error TS2322: Type ...

When you subscribe to a forkJoin, you will receive an error notification

Trying to determine when all my observables have returned their values is a challenge I'm facing. Here's my approach after including import { Observable } from 'rxjs/Rx';: let observables:any[] = []; observables.push(this.getV ...

Searching for true values in MongoDB using the query syntax can be challenging

I have a question that might be a bit embarrassing, but I need help with rendering a user search based on both location and date. Our profile object is structured like this: availability: { monday: { type: Boolean, default: false }, tuesday: { type ...

Tips for utilizing ngModel within *ngFor alongside the index?

Currently, I am dynamically generating mat-inputs using *ngFor. My goal is to store each value of [(ngModel)] in a separate array (not the one used in *ngFor) based on the index of the *ngFor elements. Here's my implementation: <div *ngFor="let i ...

Typescript enables bidirectional control of Swiper

I attempted to use the two-way control slider example from Swiper documentation, but I encountered TypeScript errors that prevented it from working correctly. Is there a way to make it compatible with TypeScript? The specific errors I received were: TS23 ...