Noob TRPC quesiton regarding response JSON

I am struggling with parsing some JSON my TRPC API is responding, and hoping to receive some guidance. I have a TRPC API which calls a table created in Prisma , as follows:
const { data: fetchedQuiz,isLoading } = api.quiz.getQuizzesByQuizID.useQuery<>({
quizID:Number.parseInt(gameID as string)
})
const { data: fetchedQuiz,isLoading } = api.quiz.getQuizzesByQuizID.useQuery<>({
quizID:Number.parseInt(gameID as string)
})
As you can see, it is being parsed as a quiz type, this is defined in prisma as follows:
model quiz {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId String
quizData Json
score Int
date DateTime
}
model quiz {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id])
userId String
quizData Json
score Int
date DateTime
}
Now, my problem is I want to access the properties of fetchedQuiz. specifcially, the quizData property. I know this JSON being returned has the properties questions, "correctAns", "selectedAnswers" and "allAnswers". However typescript complains when I try to access these properties, because the JSON isnt defined in Prisma, giving me the error: Property 'questions' does not exist on type 'string | number | boolean | JsonObject | JsonArray' This is obviously because it can't parse the properties of the quizData Json from Prisma. How would you suggest I go about ensuring this can be parsed? Some things I have tried are: Defining my own types for the response which matches the JSON, and then trying to cast the useQuery, as follows:
export interface quizDataType{
questions: string[]
correctAns: string[]
selectedAnswers:string[]
allAnswers:string[][]
}

export interface quizType{
id: number,
userId: string,
quizData: quizDataType,
score: number,
date: string
}
export interface quizDataType{
questions: string[]
correctAns: string[]
selectedAnswers:string[]
allAnswers:string[][]
}

export interface quizType{
id: number,
userId: string,
quizData: quizDataType,
score: number,
date: string
}
const { data: fetchedQuiz, isLoading } = api.quiz.getQuizzesByQuizID.useQuery<quizType>({
quizID: Number.parseInt(gameID as string),
});
const { data: fetchedQuiz, isLoading } = api.quiz.getQuizzesByQuizID.useQuery<quizType>({
quizID: Number.parseInt(gameID as string),
});
But this doesn't work, as fetchedQuiz is still of type quiz. Any suggestions are helpful.
9 Replies
Neto
Neto2y ago
prisma is giving you the correct warning as a generic Json can have multiple types on the query you can "type" the result with no inference, allowing you to use quizData as the type that you want
constraints
constraintsOP2y ago
Hmmm I am not too sure I understand, I tried to do something like
interface quizDataType{
questions: string[]
correctAns: string[]
selectedAnswers:string[]
allAnswers:string[][]
}

const quizData = fetchedQuiz.quizData as quizDataType;
interface quizDataType{
questions: string[]
correctAns: string[]
selectedAnswers:string[]
allAnswers:string[][]
}

const quizData = fetchedQuiz.quizData as quizDataType;
But I don't understand why this wouldn't work?
TS2352: Conversion of type 'string | number | boolean | JsonObject | JsonArray | null' to type 'quizDataType' may be a mistake because neither type sufficiently overlaps with the other
TS2352: Conversion of type 'string | number | boolean | JsonObject | JsonArray | null' to type 'quizDataType' may be a mistake because neither type sufficiently overlaps with the other
Neto
Neto2y ago
as unknown as quizDataType try this
constraints
constraintsOP2y ago
This worked! I've never seen this done before but thank you.
Neto
Neto2y ago
you should not use if you can
constraints
constraintsOP2y ago
what would the better practice be
Neto
Neto2y ago
the main issue is the Json type as you cant know for sure the type
constraints
constraintsOP2y ago
I see, so I suppose the optimal way would be to look into moving away from using Json in the schema
Neto
Neto2y ago
yeah
Want results from more Discord servers?
Add your server