Develop a TypeScript utility function for Prisma

Having trouble inferring the correct type for my utility function:

function customUtilityFunction<
  P, R, A extends unknown[]
>(
  prismaArgs /* Make "where" field optional as it is already defined inside findUnique method below */,
  fn: (
    prismaData /* Need to dynamically determine the same type as prismaData defined inside async function below based on prismaArgs */,
    ...args: A
  ) => Promise<R>
){
  return async function(...args: A){
    const prismaData = await prisma.session.findUnique({
      ...prismaArgs,
      where: {
        ...prismaArgs.where,
        sessionId: getSessionId()
      }
    })
    return await fn(prismaData, ...args)
  }
}

const dynamicFn = customUtilityFunction(
  { 
    include: {
      user: { userId: true }
    }
  },
  async (prismaData, arg1, arg2) => {
    //    ^? (parameter) prismaData: { ...sessionField, user: { userId: string } }
  }
)

dynamicFn(arg1, arg2)

Successfully achieved type inference on prismaData, but used methods like casting and any that are not best practices. Seeking a more proper solution.

Answer №1

This is my approach to solving the problem:

export function validateUser<
  R,
  S extends Omit<Prisma.SessionFindUniqueArgs, 'where'>,
  A extends unknown[],
>(
  prismaArgs: S,
  fn: (
    prismaData: Prisma.SessionGetPayload<typeof newPrismaArgs>,
    ...args: A
  ) => Promise<R>
) {
  const newPrismaArgs = {
    ...prismaArgs,
    where: {
      ...prismaWhereSafeSession(),
    },
  };
  return async function (...args: A) {
    const prismaData = (await prisma.session.findUnique(
      newPrismaArgs
    )) as Prisma.SessionGetPayload<typeof newPrismaArgs> | null;

    if (!prismaData) {
      redirectToLogin();
    }

    return await fn(prismaData, ...args);
  };
}

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

Tips for resolving the issue: 'Unhandled Promise Rejection: Error: Unable to resolve bare specifier "app.js" from http://localhost:3000/'

While delving into TypeScript, I have come across an error related to node modules. Upon clicking the anonymous function, it leads me to the following code snippet. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> & ...

What steps do I need to take in order for TypeScript source files to appear in the node inspector?

Currently developing a node express app with TypeScript 2.3. Compiling using tsc Interested in debugging TypeScript code using node-inspector (now included in node 6.3+) SourceMaps are enabled in my tsConfig.json file { "compilerOptions": { "targ ...

Leverage TypeScript AngularJS directive's controller as well as other inherited controllers within the directive's link function

I am currently developing an AngularJS directive in TypeScript for form validation. I am trying to understand how to utilize the directive's controller and inherit the form controller within the directive's link function. Thank you in advance! ...

What is the purpose of having a constructor in Typescript when an interface is already used for a class?

Is it necessary to have a constructor in my class if the class already implements an interface? It seems like redundant code to me. interface PersonInterface { firstname: string; lastname: string; email: string; } class Person implements Pe ...

The const keyword is not automatically inferred as a const when using conditional types for generic type parameters

Within Typescript, the const modifier can be applied to function type parameters. This ensures that the inferred type matches the literal received with as const. function identity<const T>(a: T){ return a } For example, when using identity({ a: 4 ...

Before running any unit tests, I have to address all linting issues as required by ng test

Upon running ng test, the output I receive is as follows: > ng test 24 12 2019 14:20:07.854:WARN [karma]: No captured browser, open http://localhost:9876/ 24 12 2019 14:20:07.860:INFO [karma-server]: Karma v4.4.1 server started at http://0.0.0.0:9876/ ...

Contrasting characteristics of class members in JavaScript versus TypeScript

Typescript, a superset of Javascript, requires that Javascript code must function in Typescript. However, when attempting to create class members in a typescript file using the same approach as Javascript, an error is encountered. CODE :- script.ts (types ...

Typescript not flagging an error for an object being declared without a type

I am encountering an issue with my tsconfig.json file: { "compilerOptions": { "allowJs": true, "allowSyntheticDefaultImports": true, "baseUrl": "src", "isolatedModules": true, "jsx": "preserve", "esModuleInterop": true, "forc ...

Invoking a controller from another controller in the Express framework using Typescript

Currently, I am trying to call a controller from another controller in my code. While attempting to pass parameters using {params: {task_id: String(task_id), result}}, TypeScript is flagging an error indicating that res does not have all the required attri ...

Encountering a problem with an InvalidPipeArgument in Angular 6

Here's a quick summary of the situation: I recently upgraded my application to the latest version of Angular, moving from 5 to 6. All deployments in the packages.json file were updated using the ng update command. In my application, I save a Date() ...

Exploring the Power of Chained Promise Calls

Afterwards, in the .then section, I call another promise for an HTTP request: .then(result => { this.service().then(data => {}); }); Would you say that using chained promises in this manner is correct? ...

ngOnInit unable to properly listen to event stream

I've been trying to solve a persistent issue without success. The problem involves the interaction between three key elements: the HeaderComponent, TabChangingService, and TabsComponent. Within the HeaderComponent, there are three buttons, each with a ...

Tips on designing unique field validation decorators in NestJS using GraphQL

I'm currently developing a NestJS API using apollo-server-express and have created an InputType for appointments as shown below: @InputType() export class AppointmentInput { @Field(of => String) @IsNotEmpty() name: string; @Field(o ...

Exploring the differences between importing all utilities as a whole using `import * as util from "./util"` and importing a specific function only with `import {someFunction

When comparing the two options of importing from a module, which is better: import * as util from "./Util" or import {someFunction} from "./Util"? ...

Enhance your Vuex action types in Typescript by adding new actions or extending existing

I'm new to Typescript and I'm exploring ways to add specific type structure to all Actions declared in Vue store without repeating them in every Vuex module file. For instance, instead of manually defining types for each action in every store fi ...

Personalized path-finding tree iterator

I am trying to implement a custom iterator in JavaScript that can traverse a DOM tree based on specific criteria provided by a callback function. The goal is to return an array of the nodes that match the criteria as the generator iterates through the tree ...

Effortlessly apply mapping, filtering, reducing, and more in JavaScript

Array#map and Array#filter both create a new array, effectively iterating over the original array each time. In languages like rust, python, java, c#, etc., such expression chains only iterate once, making them more efficient in certain cases. While this ...

Is it possible to pass parameters from a base class's constructor to a child class?

I'm facing an issue with my base (generic) classes where the properties are initialized in the constructor. Whenever I try to extend these classes to create more specific ones, I find myself repeating the same parameters from the base class's con ...

What is the process for creating a new Object based on an interface in Typescript?

I am dealing with an interface that looks like this: interface Response { items: { productId: string; productName: string; price: number; }[] } interface APIResponse { items: { productId: string; produc ...

Using the index in Vue.js to locate a method within an HTML file

Currently, I am attempting to make use of the reference "index" located within <tr v-for="(note, index) in noteList" v-bind:key="index" in order to call shareToPublic(index). The method selectedID() allows for the selection of the ...