P
Prisma3mo ago
neofrog.

Prisma type inference is returning weird types

I'm encountering an issue with TypeScript not properly inferring the types when using PrismaClient in my Node.js typescript application. Setup: Prisma Schema:
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Account {
id String @id @default(uuid())
telegram_id BigInt @unique
telegram_username String? @unique
}
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model Account {
id String @id @default(uuid())
telegram_id BigInt @unique
telegram_username String? @unique
}
Prisma Client Initialization:
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();
export default prisma;
Issue:
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();
export default prisma;
Issue:
When I perform a simple findUnique query, TypeScript infers the type as PrismaAccountClient<Account | null> instead of the expected model type.
const getAccount = async (telegram_id: number) => {
const account = await prisma.account.findUnique({
where: { telegram_id: telegram_id.toString() },
});

return account;
};

// Testing type inference
const testTypeInference = async () => {
const account = await getAccount(123456);

if (account) {
// TypeScript should infer that account is of type Account
// but instead it infers a complex Prisma type
console.log(account.telegram_username);
}
};

testTypeInference();
const getAccount = async (telegram_id: number) => {
const account = await prisma.account.findUnique({
where: { telegram_id: telegram_id.toString() },
});

return account;
};

// Testing type inference
const testTypeInference = async () => {
const account = await getAccount(123456);

if (account) {
// TypeScript should infer that account is of type Account
// but instead it infers a complex Prisma type
console.log(account.telegram_username);
}
};

testTypeInference();
Expected Type: account should be inferred as Account | null. Actual Type: account is inferred as Prisma
AccountClient<Account | null>. Question: How can I ensure that TypeScript infers the correct type (Account | null) for the result of the findUnique query without needing to manually set the types? Any help would be greatly appreciated!
13 Replies
neofrog.
neofrog.3mo ago
Apologies for all the weird underlines in my post, i edited it on my phone before i head to sleep
RaphaelEtim
RaphaelEtim3mo ago
Hi @neofrog. The return type of the method is Prisma.Prisma__AccountClient which will either be an object with the account data (if found) or null if no account matches the filter criteria is correct. You can explicitly assert the type of the returned value to Account | null.
const res = await prisma.account.findUnique({
where:{
id: "1"
}
}) as Account | null
const res = await prisma.account.findUnique({
where:{
id: "1"
}
}) as Account | null
neofrog.
neofrog.3mo ago
Shouldn’t it work without asserting?
Ustice
Ustice3mo ago
Why are you converting telegram_id to a string in your query? That seems unnecessary. Do you still have the type error if you use the direct query, rather than calling getAccount?
neofrog.
neofrog.3mo ago
Im converting it because i created a new function to demonstrate my problem and it was just easier than changing it in the db. And yeah i get the same issue using it directly It’s happening all throughout my project, I’ve tried nuking node modules and cache, and reinstalling re-generating prisma types. Ive tried numerous different tsconfig setups. The only way i seem to be able to get it to work is asserting at every step along the way and even then it still is buggy as hell
Ustice
Ustice3mo ago
Prisma queries don’t really return the model types. Their types are dynamic, based on what you query. Are you not getting correct type inference? The types are complex. You shouldn’t need to be making any type assertions—they’re dangerous. You’ll so much better to use those dynamic types. The Prisma docs have info on how to work with them.
RaphaelEtim
RaphaelEtim3mo ago
I do agree with Ustice that you don't need to assert the Prisma Queries. For the example you shared,
const res = await prisma.account.findUnique({
where:{
id: "1"
}
})
const res = await prisma.account.findUnique({
where:{
id: "1"
}
})
if you hover over res variable you should get the correct return type shown. See the image example
No description
neofrog.
neofrog.3mo ago
what your showing me is exactly what i expect to happen, i dont want to be asserting. I created a completely blank typescript project with prisma and im still getting the weird types. Could it be anything to do with my tsconfig.json? { "compilerOptions": { "target": "ES2020", "module": "commonjs", "lib": ["ES2020"], "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "moduleResolution": "node", "typeRoots": ["node_modules/@types"], "types": ["node"] }, "include": ["src/*/.ts"], "exclude": ["node_modules"] }
Ustice
Ustice3mo ago
No nothing is wrong. In the type above, you just need to make sure that you’re handling the null case. Make sure that you run prisma generate if you made any scheme changes. I’ll be home this weekend. PM me, and I can do a screen-sharing session to see what is going on first-hand.
Ustice
Ustice3mo ago
Nope. I got it. Your getAccount is typed wrong.
No description
Ustice
Ustice3mo ago
Try not to use manual types for function parameters like you did. It’s too easy to get them wrong. And it’s possible that they can change as your database evolves. It’s much better to use the generated types, as they will update when you run generate. You’re sending a string instead of number, and that doesn’t work. telegram_id is of type number | bigint | undefined. string is incompatible. @neofrog. Did you get it working?
neofrog.
neofrog.2mo ago
hey! sorry been on holiday. Nope i didn't, its been a pain tbh
Ustice
Ustice2mo ago
I’ll be online in about an hour from now. I accepted your friend request. If you ping me, I can do a screensharing with you if you would like.
Want results from more Discord servers?
Add your server