Convert all key types into arrays of that key type using a TypeScript utility type

My interface (type) is currently defined as:

 interface User {
     name: string,
     id: string,
     age: number,
     town: string
 }

I have a function now that will search for Users based on specific fields. I prefer not to manually declare an additional type UserFilter like this:

 interface UserFilter {
     name: string[],
     id: string[],
     age: number[],
     town: string[]
 }

Instead, I wish to achieve the following functionality:

function findUsers(filter: Partial<UserFilter>) {
   if (filter.id) {
    mySQLQueryBuilder.whereIn('id', filter.id)
   }
   ...
}

The idea is to have each key in User represented as a scalar and in UserFilter as an array of the same type.

I believe creating a separate type like UserFilter, which is so similar to User, adds unnecessary complexity and potential for errors during maintenance.

My ideal solution would involve using TypeScript's utility types to automatically convert the fields of the User type into arrays of the same type. I'd call this transformation ConvertAllKeysToArrays.

function findUsers(filter: Partial<ConvertAllKeysToArrays<User>>) {
   if (filter.id) {
    mySQLQueryBuilder.whereIn('id', filter.id)
   }
   ...
}

Thank you

Answer №1

Although there is no built-in utility type for this specific scenario, we can create our own using mapped types.

type ConvertToArrays<T> = {
    [Key in keyof T]: T[Key][]
}

type ProductFilter = ConvertToArrays<Product>

Playground

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

Grab a parameter from the URL and insert it into an element before smoothly scrolling down to that

On a button, I have a URL that looks like this: www.mywebsite.com/infopage?scrollTo=section-header&#tab3 After clicking the button, it takes me to the URL above and opens up the tab labeled tab3, just as expected. However, I would like it to direct m ...

Removing AWS-CDK Pipelines Stacks Across Multiple Accounts

Currently, I am utilizing pipelines in aws-cdk to streamline the process of automating builds and deployments across various accounts. However, I have encountered an issue where upon destroying the pipeline or stacks within it, the respective stacks are ...

Using {children} in NextJS & Typescript for layout components

I am looking to develop a component for my primary admin interface which will act as a wrapper for the individual screens. Here is the JavaScript code I have: import Header from '../Header' function TopNavbarLayout({ children }) { return ...

The parameter 'host: string | undefined; user: string | undefined' does not match the expected type 'string | ConnectionConfig' and cannot be assigned

My attempt to establish a connection to an AWS MySQL database looks like this: const config = { host: process.env.RDS_HOSTNAME, user: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, port: 3306, database: process.env.RDS_DB_NAME, } ...

Troubleshooting React child problems in TypeScript

I am facing a coding issue and have provided all the necessary code for reference. Despite trying numerous solutions, I am still unable to resolve it. export class JobBuilderOptimise extends React.Component<JobBuilderOptimiseProps & JobBuilderOptim ...

Maintain hook varieties during implementation of array deconstruction

I have been developing a straightforward hook to export animation helper and element reference. import { gsap } from 'gsap'; import { useRef } from 'react'; export function useTween<R extends gsap.TweenTarget>(vars: gsap.TweenVar ...

Implementing Firebase as an Authentication Middle Layer for Express.js

I am currently working on developing an authentication middleware to verify the presence of a valid firebase token in the request header. Here's the code snippet: auth.ts import * as firebase from 'firebase-admin'; import { NextFunction, Re ...

Problem with Invoking method of parent component from child component in Angular 4

Despite having all my event emitters set up correctly, there's one that seems to be causing issues. child.ts: @Component({ ... outputs: ['fileUploaded'] }) export class childComponent implements OnInit { ... fileUploaded ...

The React component continuously refreshes whenever the screen is resized or a different tab is opened

I've encountered a bizarre issue on my portfolio site where a diagonal circle is generated every few seconds. The problem arises when I minimize the window or switch tabs, and upon returning, multiple circles populate the screen simultaneously. This b ...

Can someone help me figure out how to simulate an express middleware class method using jest and supertest?

I'm facing some challenges trying to achieve the desired outcome when mocking a method in a class using jest and supertest. I'm specifically looking for a solution that can help me bypass the verifyAuthenticated method with a mocked version in or ...

Refreshing a page with a 404 error in Angular 2 while in production mode and without the useHash configuration

I've encountered an issue while using Angular 2 without the useHash feature. When trying to visit the URL directly in a browser, I'm getting a 404 not found error. I have searched extensively and attempted various solutions including: Adding L ...

Error encountered: The database is not found during the migration creation process in MikroORM

Attempting to create migrations with mikroORM has been a challenge as I am unable to generate the table itself. The error message indicating that the database "crm" does not exist leaves me puzzled about what steps I may have missed. Here is the code snip ...

The attribute 'forEach' is not recognized on the data type 'string | string[]'

I'm experiencing an issue with the following code snippet: @Where( ['owner', 'Manager', 'Email', 'productEmail', 'Region'], (keys: string[], values: unknown) => { const query = {}; ...

Cloning a repository does not support Typescript compilation

After creating an Angular2 component, I wanted to share the code with my colleagues. Therefore, I uploaded the code to Github, cloned the repository, ran npm install, and then npm run tsc. However, I encountered the following errors: error TS2318: Cannot ...

Utilize *ngFor in Angular 9 to showcase both the key and values of an array

JSON Data { "cars": { "12345": [1960, 1961, 1962], "4567": [2001, 2002] } } HTML Template <strong>Plate and Year</strong> <div *ngFor="let car of cars"> {{car}} </div> This should be di ...

Angular 2: Capturing scroll events from the parent element within a Directive

One of the challenges I encountered is with a directive called [appInvalidField] that functions like a custom tooltip for validation purposes. To ensure it appears above everything else within dialogs, I attach it to the body and position it near the relev ...

Typescript and Apollo Client return types intertwined

My goal is to create a simple function within a class that generates an Apollo Client. Below is the code I have implemented: import appConfig from 'config/app-config'; import { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/clie ...

Enhancing TypeScript functionality by enforcing dynamic key usage

Is there a way to ensure specific keys in objects using TypeScript? I am attempting to define a type that mandates objects to have keys prefixed with a specific domain text, such as 'create' and 'update': const productRepoA: Repo = { } ...

Creating dynamic key objects in TypeScript with index signatures: A beginner's guide

How can the code be optimized to automatically initialize a new product type without adding extra lines of code? Failure to initialize the variable results in a syntax error. enum ProductType { PC = 'pc', LAPTOP = 'laptop', TV ...

What is the best way to transfer information from the window method to the data function in a Vue.js application?

Is there a way to transfer information from the window method to the data function in a vuejs component? Take a look at my window method: window.authenticate = function(pid, receiptKey) { console.log("Authentication"); console.log(this) localStorag ...