Generating a Key/Value pair using a factory limits the properties and their corresponding data types to those defined within a class

Imagine I have a hypothetical vehicle:

public class Car 
{
  ManufacturedYear: number;
  Manufacturer: string;
}

I am aiming to construct a well-defined tree of criteria that can be serialized to JSON, used on the client side for filtering, or on the server side for generating an SQL where clause. Here is my current progress:

export class FilterFactory {
  private constructor() {
  }

  public static createFilter<TModel, TKey extends keyof TModel>(
    key: TKey,
    value: TModel[TKey],
  ): IFilterCriteria<TModel, TKey> {
    return new FilterCriteria(key, value);
  }
}

export interface IFilterCriteria<TModel, TKey extends keyof TModel> {
  property?: TKey;
  value?: TModel[TKey];
  operator? : 'and' | 'or';  //tbd enum
  criterias?: ?? 
}

class FilterCriteria<TModel, TKey extends keyof TModel>
  implements IFilterCriteria<TModel, TKey>
{
  public property?: TKey;
  public value?: TModel[TKey];
  public operator? : 'and' | 'or';  //tbd enum
  public criterias?: ?? 

  constructor() {}
}

Example in Codepen

As demonstrated below:

var noerror = FilterFactory.createFilter<Car, 'ManufacturedYear'>('ManufacturedYear', 2008);

var expectederror = FilterFactory.createFilter<Car, 'ManufacturedYear'>('ManufacturedYear', 'asdf');

The challenge lies in eliminating the need to specify the key twice, both as a generic and as a parameter. Thus, I aim to achieve one of the following:

var noerror = FilterFactory.createFilter<Car, 'ManufacturedYear'>(2008);
// or
var noerror = FilterFactory.createFilter<Car>('ManufacturedYear', 2008);

Answer №1

This solution may not be as sleek as I initially hoped, but it is still quite decent; the code is at least easy to read:

Summary:

class Car {
  ManufacturedYear: number;
  Manufacturer: string;
}

const manuYearFilter = FilterFactory.with<Car>().create("ManufacturedYear", 2009);

Here is the implementation:

export interface IFilter {
}

export class FilterFactory<TModel> {
  private constructor() {
  }

  public  create<TKey extends keyof TModel>(
    key: TKey,
    value: TModel[TKey],
  ): IFilter {
    return new Filter(key, value);
  }

  public static with<TModel>() {
    return new FilterFactory<TModel>();
  }
}

class Filter<TModel, TKey extends keyof TModel>
  implements IFilter
{
  constructor(
    public property: TKey,
    public value: TModel[TKey],
  ) {
  }
}

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

Can a mandatory attribute be made non-essential within an intersection category?

Currently, I am customizing the Material UI date picker and exploring ways to make the required props optional since default values are already provided by the parent component. This is my current code: import React, { useState } from "react"; i ...

Determining if an item is empty, undefined, or null in Angular: a guide

I received a .json file structured as data [0 ... n]. Each position in the data array contains an object with various attributes, such as: {photo1, photo2, photo3 ... photoN} For a visual representation of how the json file is formatted, you can check ...

Having trouble generating a unique BlockEmbed with Quill 2.0-dev3

After using Quill 1.3.7 successfully with custom embed blots, we decided to upgrade to 2.0.0-dev3 for new features. However, this upgrade caused our custom blots to break, resulting in the error message: Class constructor BlockEmbed cannot be invoked with ...

Exploring the use of .pipe with Angular Jest for testing

Currently, I am trying to test the following .ts file: create(entityResourceID, params: any): Observable <any>{ const url = `${this.apiUrl}/${entityResourceID}/assignee`; return this.http.post(url, params).pipe( map(() ...

What could be the reason behind the absence of this.props.onLayout in my React Native component?

In my React Native app, I have the below class implemented with Typescript: class Component1 extends React.Component<IntroProps, {}> { constructor(props){ super(props) console.log(props.onLayout) } ... } The documentation for the View ...

Determining the height of dynamically rendered child elements in a React application

Looking for a way to dynamically adjust the heights of elements based on other element heights? Struggling with getting references to the "source" objects without ending up in an infinite loop? Here's what I've attempted so far. TimelineData cons ...

One method to make this code more concise

Is there a way to condense this code? I want 'All' to be displayed at index 0. Can I have multiple conditions, such as displaying 'All' at index 0, performing an action at every other index, and another action at the last index? I enc ...

Unable to locate the reference to 'Handlebars' in the code

I am currently attempting to implement handlebars in Typescript, but I encountered an error. /// <reference path="../../../jquery.d.ts" /> /// <reference path="../../../require.d.ts" /> My issue lies in referencing the handlebars definition f ...

Currency Digital Style

I'm working on converting the amount retrieved from my API into a format specific to the user's locale. When using the console: Intl.NumberFormat('en-IN').format(450000) // "4,50,000" But in an Angular 2 component template: {{ Intl. ...

The navigation function in Angular, this.router.navigate, is causing issues and

I've encountered a peculiar issue. There's a logout function that is activated whenever I receive a 401 response from any API I interact with. The function looks like this: constructor( private router: Router, ) {} logout(router1: Router ...

Expanding Typescript modules with a third-party module and namespace

Looking to enhance the capabilities of the AWS SDK DynamoDB class by creating a new implementation for the scan method that can overcome the 1 MB limitations. I came across some helpful resources such as the AWS documentation and this insightful Stack Over ...

Using TypeScript to spread props in React

Here is some code snippet that I've been working with: type WrapperProps = { wrapperProp: string }; const Wrapper: React.FC<WrapperProps> = ({ children }) => <div>{children}</div>; type MyCmpnntProps = { myCmpnntProp: string }; ...

"Angular 2: Organize and refine data with sorting and

Sorting and filtering data in Angularjs 1 can be done using the following syntax: <ul ng-repeat="friend in friends | filter:query | orderBy: 'name' "> <li>{{friend.name}}</li> </ul> I have not been able to find any ex ...

Error handling in Angular is not properly managing the custom exception being thrown

I am currently working on an Angular 12 application and I have a requirement to implement a custom ErrorHandler for handling errors globally. When I receive an error notification from the backend, I subscribe to it in the ToolService using this.notificati ...

Issue TS2351: It appears that this particular expression is not capable of being constructed. (Utilizing AJV in a

Currently, I am encountering an issue while trying to use AJV with Typescript. I previously raised a similar concern in the ajv repository but unfortunately did not find a solution. The problem arises when attempting to import the Ajv module as follows: ...

Issue with the compatibility between Angular Material version 11.0.3 and Tailwind CSS causing functionality problems

Currently, I am utilizing Angular CLI 11.0.6 on NodeJS 14.15.4 to develop a web application for expanding my knowledge of Angular (11.0.7) in conjunction with TailwindCSS 2.0.2. Following a tutorial to install Tailwind, I had previously integrated Angular ...

Is there a way to use code to automatically toggle the checkbox to either true or false?

<label class="switch"> <input type="checkbox" id="balanced" [(ngModel)]="balancedAmount" (click)="onNoClick($event)"> <span class="slider round"></span> ...

Having trouble with the rowNode functionality in PrimeNG TreeTable

I am currently utilizing the PrimeNG Treetable component from https://www.primefaces.org/primeng/#/treetable I seem to be encountering issues with retrieving data from the service. Below is a snippet of my code: HTML <p-treeTable [value]="temp"> & ...

Error: The function onSelect is not defined and cannot be executed by clicking on the HTML element with the id of "onclick" at line

I keep encountering this error message in my console: Uncaught ReferenceError: onSelect is not defined at HTMLAnchorElement.onclick (VM998 :14) This is the list data in my .html file: <ul class="nav navbar-nav"> <li& ...

React experimental is encountering an issue with missing property "" $fragmentRefs"" when relaying fragments

Details Recently, I decided to explore React experimental features with concurrent mode and relay. Even though I have never used relay before, I managed to make progress but ran into some issues. Initially, using the useLazyLoadQuery hook without any frag ...