Why does typescript change the type of user whenever I add this to my return function?

Hi guys, I am trying to understand this about typescript/trpc. Why does the type here keep changing? Why is it not accepting me to type user.data.... ?
46 Replies
Kasper
Kasper•2y ago
share your code in a sandbox it's very hard to help without full context alternatively, cut and paste the relevant code into discord using code syntax:
const foo = "bar";
const foo = "bar";
or at the very least don't post screenshots where your code is almost entirely covered by an error or type resolution 🙂
CaptainStarz
CaptainStarz•2y ago
Seems like you’re trying to access react query inside trpc router
barry
barry•2y ago
You don't run queries inside a query. Yeah what Captain said.
Gabriel
GabrielOP•2y ago
Oh... That would be very good if I could do that
barry
barry•2y ago
No... Just? Make your code reusable.
Gabriel
GabrielOP•2y ago
What do you mean? I was meaning to make it reusable. Make one query, and then I can reuse it inside other queries But apparently that's not ideal
barry
barry•2y ago
You can use middleware
barry
barry•2y ago
Middlewares | tRPC
You are able to add middleware(s) to a procedure with the t.procedure.use() method. The middleware(s) will wrap the invocation of the procedure and must pass through its return value.
Gabriel
GabrielOP•2y ago
Sorry about the screenshots. Next time I will share it by pasting the code
barry
barry•2y ago
Or the simple good old function that you use both places Or 1965's copy paste.
Gabriel
GabrielOP•2y ago
Interesting. Middlewares...
Kasper
Kasper•2y ago
if you find yourself wanting to communicate between multiple routers, chances are you might want to go learn about software architecture patterns specifically layered architecture I don't know your use case, but a common one is the repository pattern having some code abstracted away into a repository that is then reused by multiple services (or in trpc, routers) instead of having services communicate with each other directly. Imo, that's an anti pattern with tRPC (unless you're doing integration testing specifically, then you can use https://trpc.io/docs/server-side-calls)
Gabriel
GabrielOP•2y ago
/**
* Reusable middleware to ensure
* users are logged in
*/
const isAuthed = t.middleware(async ({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
const userObj = await ctx.prisma.user.findUnique({
where: {
id: ctx.session.user.id
}
})
if (!userObj){
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR"})
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
user: userObj
},
});
});

/**
* Protected procedure
**/
export const protectedProcedure = t.procedure.use(isAuthed);
/**
* Reusable middleware to ensure
* users are logged in
*/
const isAuthed = t.middleware(async ({ ctx, next }) => {
if (!ctx.session || !ctx.session.user) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
const userObj = await ctx.prisma.user.findUnique({
where: {
id: ctx.session.user.id
}
})
if (!userObj){
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR"})
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
user: userObj
},
});
});

/**
* Protected procedure
**/
export const protectedProcedure = t.procedure.use(isAuthed);
I just felt that I didn't want to always use ctx.prisma.user.findUniqueI() everytime I wanted to get the user object from db. I made this middleware for me to have the user object. Would this be ok? That being said, it would do a SQL call every single protected procedure, which might be suboptimal And slow down the service for when I don't need to call prisma
Kasper
Kasper•2y ago
middlewares are great for code reuse, but keep in mind they run all the time for the procedures you apply them to. if you want to reuse some code in the middle of some arbitrary procedure, they're not as ergonomic to work with. in that case you're better off just creating a function
barry
barry•2y ago
Make a different procedure
Kasper
Kasper•2y ago
I assume you're using nextauth with the default t3 setup? in my experience you should have all the things you need for the user already in the session user object.
Gabriel
GabrielOP•2y ago
Yep. Nextauth
Kasper
Kasper•2y ago
that's the point of a session and if you need more things in the session, you should probably look into updating your nextauth integration and enriching your session with the things you are missing instead of manually querying for it in a middleware
Gabriel
GabrielOP•2y ago
Hummm I see
Kasper
Kasper•2y ago
https://create.t3.gg/en/usage/next-auth#adding-new-fields-to-your-models Sorry, that was not the link I had in mind I meant this: https://create.t3.gg/en/usage/next-auth#inclusion-of-userid-on-the-session
The same pattern can be used to add any other data to the session object, such as a role field, but should not be misused to store sensitive data on the client.
The same pattern can be used to add any other data to the session object, such as a role field, but should not be misused to store sensitive data on the client.
Gabriel
GabrielOP•2y ago
Im reading it[
callbacks: {
async session({ session, user }) {
const userObj = await prisma.user.findUnique({
where: {
id: user.id
}
})

if (session.user && userObj?.activeWorkspaceId) {
session.user.id = user.id;
session.user.activeWorkspaceId = userObj?.activeWorkspaceId
}
return session;
},
},
callbacks: {
async session({ session, user }) {
const userObj = await prisma.user.findUnique({
where: {
id: user.id
}
})

if (session.user && userObj?.activeWorkspaceId) {
session.user.id = user.id;
session.user.activeWorkspaceId = userObj?.activeWorkspaceId
}
return session;
},
},
This is what I did, then I needed to access a certain property on my session[
Kasper
Kasper•2y ago
you shouldn't need to query prisma again
Gabriel
GabrielOP•2y ago
That I created for my User model What do you mean?
Kasper
Kasper•2y ago
async session({ session, user }) {
async session({ session, user }) {
^ The user variable here should be your user object, no?
Gabriel
GabrielOP•2y ago
Hummm[
Kasper
Kasper•2y ago
are you not using the prismaprovider with nextauth?
Gabriel
GabrielOP•2y ago
Yes, but, prisma doesnt bu default provide me with the entire User object. Only image, email, id, etc I am Oh wait
Kasper
Kasper•2y ago
are you sure? iirc you should get the entire thing
Gabriel
GabrielOP•2y ago
Yea, it is not there by default. Session interface is defined at next-auth.d.ts, and even when I add my custom activeWorkspaceId: string to it, whenever I use the session object, it doesnt have the property I wanted So, that's why I thought about using prisma again to fetch the property inside the table So I can add it to session
Kasper
Kasper•2y ago
I'm not 100% sure, but I think it should be the entire object. It could be that you haven't augmented your typescript definition properly. Have you logged the runtime data of user to confirm what you actually get?
Gabriel
GabrielOP•2y ago
I had to do this
interface Session {
user?: {
id: string;
activeWorkspaceId: string
} & DefaultSession["user"];
}
interface Session {
user?: {
id: string;
activeWorkspaceId: string
} & DefaultSession["user"];
}
I'll try
Gabriel
GabrielOP•2y ago
Gabriel
GabrielOP•2y ago
Thats what I get lmao Maybe theres a way for nextauth to fetch all of the properties for session
Kasper
Kasper•2y ago
yeah I checked the docs and found nothing I am not a fan of nextauth. If feels like a half baked product.
Gabriel
GabrielOP•2y ago
How do you do it for your t3 app? If you have more columns for User table?
Kasper
Kasper•2y ago
I don't use nextauth LuL
Gabriel
GabrielOP•2y ago
Agreed Ooh lmao ahuwauhw
Kasper
Kasper•2y ago
that's my solution, just use something else KEKYou in all seriousness, you should be fine doing another prisma query then
Gabriel
GabrielOP•2y ago
Yeah, i'll do that. For now And I'll look into middleware stuff you mentioned
Kasper
Kasper•2y ago
pretty sure the session callback is only called when the session starts so it shouldn't be expensive
Gabriel
GabrielOP•2y ago
Yeah. That's what I thought. I hope so Thank you @Kasper . Much love
Kasper
Kasper•2y ago
You're welcome :). GL!
splitfire?
splitfire?•2y ago
I started using ts and trpc recently and I see this happen sometimes where a variable shows as randomly returning as any in trpc even tho im sure the db returns something, usually I just restart the ts server and it fixes itself
Unknown User
Unknown User•2y ago
Message Not Public
Sign In & Join Server To View
Gabriel
GabrielOP•2y ago
@edgythiccboy night owl 😉
Want results from more Discord servers?
Add your server