yeetcode.io
yeetcode.io
Explore posts from servers
TtRPC
Created by yeetcode.io on 7/2/2024 in #❓-help
The inferred type of 'trpc' cannot be named without a reference to '...'
I have a monorepo setup like this: root -tsconfig.json -frontend --tsconfig.json -backend --tsconfig.json I added a reference in the client tsconfig:
"references": [
{
"path": "../backend"
}
],
"references": [
{
"path": "../backend"
}
],
I added "composite": true to my backend tsconfig. In my root tsconfig, I have:
{
"references": [
{
"path": "./backend"
},
{
"path": "./frontend"
}
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
{
"references": [
{
"path": "./backend"
},
{
"path": "./frontend"
}
],
"files": [],
"include": [],
"exclude": ["**/node_modules"]
}
However, now in my client, when I create my trpc instance: export const trpc = createTRPCReact<AppRouter>(); I get a bunch of typing errors:
The inferred type of 'trpc' cannot be named without a reference to '../../../backend/node_modules/.prisma/client'. This is likely not portable. A type annotation is necessary.ts(2742)
The inferred type of 'trpc' cannot be named without a reference to '../../../backend/node_modules/@types/express'. This is likely not portable. A type annotation is necessary.ts(2742)
The inferred type of 'trpc' cannot be named without a reference to '../../../backend/node_modules/.prisma/client'. This is likely not portable. A type annotation is necessary.ts(2742)
The inferred type of 'trpc' cannot be named without a reference to '../../../backend/node_modules/@types/express'. This is likely not portable. A type annotation is necessary.ts(2742)
Where is this coming from and how can I fix it?
38 replies
TtRPC
Created by yeetcode.io on 7/2/2024 in #❓-help
My TRPC hooks are getting typed as `any`
I'm using a Typescript + Express backend (Node.js, version 18), and a React Native (Typescript) frontend. For some reason by TRPC tanstack-query hooks don't seem to be typing things correctly. I am trying to understand why. I have a monorepo setup with a file structure like this: root -frontend -backend So the frontend and backend files can import from each other, and everything lives under one .git in the root. In my backend, I create a router and export the type:
const appRouter = router({
myName1: myRouter1,
myName2: myRouter2,
});

export type AppRouter = typeof appRouter;
const appRouter = router({
myName1: myRouter1,
myName2: myRouter2,
});

export type AppRouter = typeof appRouter;
Here is an example typing I get when I hover over a procedure in one of my subrouters. I don't return any in any of my procedures.
const myProcedureName: QueryProcedure<{
input: number;
output: ({
author: {
id: number;
};
} & {
myDataField: number;
})[];
}>
const myProcedureName: QueryProcedure<{
input: number;
output: ({
author: {
id: number;
};
} & {
myDataField: number;
})[];
}>
In my React Native app, I import the type:
import {createTRPCReact} from '@trpc/react-query';
import type {AppRouter} from 'my/file/path/to/backend';
export const trpc = createTRPCReact<AppRouter>();
import {createTRPCReact} from '@trpc/react-query';
import type {AppRouter} from 'my/file/path/to/backend';
export const trpc = createTRPCReact<AppRouter>();
Then in my App.tsx, I create the trpcClient:
const trpcClient = trpc.createClient({
links: [
httpBatchLink({
url: `${API_URL}/trpc`,
}),
],
});
const trpcClient = trpc.createClient({
links: [
httpBatchLink({
url: `${API_URL}/trpc`,
}),
],
});
Now when I use a hook:
// useProfile.ts
export default function useProfile(id: number) {
return trpc.user.myProcedureName.useQuery(id);
}

//MyComponent.ts
function Component() {
const {data} = useProfile(id);
// useProfile.ts
export default function useProfile(id: number) {
return trpc.user.myProcedureName.useQuery(id);
}

//MyComponent.ts
function Component() {
const {data} = useProfile(id);
My data gets typed as any, what am I doing wrong in my setup?
7 replies
PPrisma
Created by yeetcode.io on 6/6/2024 in #help-and-questions
Question about designing friend request / follow system with relational tables
I'm using Prisma on top of PostgreSQL. In my app, I have a Follow table, denoting follow relationships, and a FollowRequest table, denoting pending follow requests. I've enforced that in both the Follow and FollowRequest table, the permutation of two users is unique. So we can't have multiple duplicate FollowRequests. I want to write a function for my expres s server that can reject a follow request. I have the user context already. I see two ways of writing it: 1) Get the followRequestId from the request. Lookup the FollowRequest row in Prisma. If the user context matches with the FollowRequest, delete the row. This is two sequential database interactions. 2) Get the sourceUserId and the targetUserId in the request (basically the person who made the follow request, and the person who was requested). I can then check if the user context matches the targetUserId, but this time I don't need a database read to do so. I can then perform a Prisma delete with the unique combination (sourceUserId, targetUserId). This is just one database interaction. The second one feels a bit odd, because I'm not working with the unique followRequestId which is part of my FollowRequest table. I'm leveraging the fact that (sourceUserId, targetUserId) is unique. Are there recommendations for how to approach this? I'm asking here because I'm not sure if I'm missing considerations on efficiency / how Prisma works.
4 replies