juico
juico16mo ago

Type return error when using mongoose.

node - v16.15.1 npm I'm somewhat new to trpc. Using it with mongoose. Love it so far althought I do have a problem with how types are returned. For example I have a simple procedure:
export const getUser = procedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {
const db = await connectDB();
const user: UserDocument | null = await User.findOne({
walletAddress: opts.input.walletAddress,
});
return user;
});
export const getUser = procedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {
const db = await connectDB();
const user: UserDocument | null = await User.findOne({
walletAddress: opts.input.walletAddress,
});
return user;
});
This should return either UserDocument or null. I call it in my client:
const getUser = trpc.getUser.useMutation();
const currentUser: UserDocument | null = await getUser.mutateAsync({
walletAddress: userWalletAddress
})
const getUser = trpc.getUser.useMutation();
const currentUser: UserDocument | null = await getUser.mutateAsync({
walletAddress: userWalletAddress
})
But this gives error:
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is not assignable to type 'UserDocument | null'.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is missing the following properties from type 'UserDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is not assignable to type 'UserDocument | null'.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is missing the following properties from type 'UserDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.
So it seems to be returning a different type than specified.
2 Replies
Alex / KATT 🐱
Alex / KATT 🐱16mo ago
I haven't used mongoose for about ten years but IIRC it has quite fat instance objects with methods on them. It's possible that they are not serializable through JSON and that it's why it fails Oh, this is a typescript error Just remove the type assertions E.g.
const user = await createUser.mutateAsync(...
const user = await createUser.mutateAsync(...
Dont set the return value, we will transform it to an equivalent of what JSON stringify does
juico
juicoOP16mo ago
When I hover over user it does give me the json of all values it returns, but that is not a defined type. So I if there are other function that need a specific type like UserDocument, how do I make sure that this is UserDocument? So for example I have another trpc procedure: const newDeck = await createNewDeck.mutateAsync({ deckName: deckName, walletAddress: user?.walletAddress ?? '', image: imageUrl }) When I hover over newDeck I can see the values:
const createNewDeck: UseTRPCMutationResult<{
walletAddress: string;
_id: string;
default: boolean;
readonly URL: string;
alinkColor: string;
readonly all: {
[x: number]: {
id: string;
onfullscreenchange: null;
onfullscreenerror: null;
readonly ownerDocument: {
readonly URL: string;
... 187 more ...;
readonly lastElementChild: ... | null;
};
... 95 more ...;
readonly assignedSlot: {
...;
} | null;
};
readonly length: number;
};
... 188 more ...;
deckName: string;
}, TRPCClientErrorLike<...>, {
...;
}, unknown>
const createNewDeck: UseTRPCMutationResult<{
walletAddress: string;
_id: string;
default: boolean;
readonly URL: string;
alinkColor: string;
readonly all: {
[x: number]: {
id: string;
onfullscreenchange: null;
onfullscreenerror: null;
readonly ownerDocument: {
readonly URL: string;
... 187 more ...;
readonly lastElementChild: ... | null;
};
... 95 more ...;
readonly assignedSlot: {
...;
} | null;
};
readonly length: number;
};
... 188 more ...;
deckName: string;
}, TRPCClientErrorLike<...>, {
...;
}, unknown>
But there is no definition of the type so when I want to use it in another method like this one: playerDeckActions.setAddDeckToList(newDeck) The method expects DeckDocument but newDeck is not recognized as such: function setAddDeckToList(deck: DeckDocument) { const currentDeckList = JSON.parse(JSON.stringify(playerDecksState.playerDecks)); currentDeckList.push(deck) setPlayerDecks((state: any) => ({ ...state, playerDecks: [...currentDeckList], })) } and so it will throw a same error:
Argument of type '{ walletAddress: string; _id: string; .... is missing the following properties from type 'DeckDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.ts(2345)
Argument of type '{ walletAddress: string; _id: string; .... is missing the following properties from type 'DeckDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.ts(2345)