Passing data as props to component
Answered
evandabest posted this in #help-forum
Plz help me. This might be a typescript bug but I'm trying to pass a user object to my DisplayEmail prop but I keep getting this type error.
I'm still new to Typescript and NextJs. If there is an easier way to do this, plz lmk. Thank you.
This is my page.tsx
The following is my DisplayEmail component
Type 'UserResponse' is not assignable to type 'User'.
Type '{ data: { user: User; }; error: null; }' is missing the following properties from type 'User': id, aud, role, email, and 11 more.ts(2322)
displayEmail.tsx(22, 5): The expected type comes from property 'user' which is declared here on type 'IntrinsicAttributes & DisplayEmailProps'
(property) DisplayEmailProps.user: UserI'm still new to Typescript and NextJs. If there is an easier way to do this, plz lmk. Thank you.
This is my page.tsx
import { createClient } from "@/utils/supabase/server";
import DisplayEmail from "../components/DisplayEmail";
export async function getProfile() {
const supabase = createClient();
const user = await supabase.auth.getUser();
console.log(user);
return user;
}
interface DisplayEmailProps {
user: any;
}
const Home : ({}: DisplayEmailProps) => Promise<JSX.Element> = async ({}) => {
const user1 = await getProfile();
return (
<div>
{user1 && <DisplayEmail user={user1} />}
</div>
);
};
export default Home;The following is my DisplayEmail component
"use client"
interface User {
id: string;
aud: string;
role: string;
email: string;
email_confirmed_at: string;
phone: string;
confirmation_sent_at: string;
confirmed_at: string;
last_sign_in_at: string;
app_metadata: object;
user_metadata: object;
identities: Array<any>;
created_at: string;
updated_at: string;
is_anonymous: boolean;
}
interface DisplayEmailProps {
user: User;
}
const DisplayEmail: React.FC<DisplayEmailProps> = ({ user }: DisplayEmailProps) => {
return (
<div>
<h2>User Email</h2>
<p>{user.email}</p>
</div>
);
};
export default DisplayEmail;Answered by Turkish Van
Here is the corrected
User type that seems to be working for me:type User = {
aud: string | null;
banned_until?: string | null;
confirmation_sent_at?: string | null;
confirmation_token?: string | null;
confirmed_at?: string | null;
created_at: string | null;
deleted_at?: string | null;
email?: string | null;
email_change?: string | null;
email_change_confirm_status?: number | null;
email_change_sent_at?: string | null;
email_change_token_current?: string | null;
email_change_token_new?: string | null;
email_confirmed_at?: string | null;
encrypted_password?: string | null;
id: string;
instance_id?: string | null;
invited_at?: string | null;
is_anonymous?: boolean;
is_sso_user?: boolean;
is_super_admin?: boolean | null;
last_sign_in_at?: string | null;
phone?: string | null;
phone_change?: string | null;
phone_change_sent_at?: string | null;
phone_change_token?: string | null;
phone_confirmed_at?: string | null;
raw_app_meta_data?: JSON | null;
raw_user_meta_data?: JSON | null;
reauthentication_sent_at?: string | null;
reauthentication_token?: string | null;
recovery_sent_at?: string | null;
recovery_token?: string | null;
role?: string | null;
updated_at?: string | null;
};18 Replies
@evandabest Plz help me. This might be a typescript bug but I'm trying to pass a user object to my DisplayEmail prop but I keep getting this type error.
txt
Type 'UserResponse' is not assignable to type 'User'.
Type '{ data: { user: User; }; error: null; }' is missing the following properties from type 'User': id, aud, role, email, and 11 more.ts(2322)
displayEmail.tsx(22, 5): The expected type comes from property 'user' which is declared here on type 'IntrinsicAttributes & DisplayEmailProps'
(property) DisplayEmailProps.user: User
I'm still new to Typescript and NextJs. If there is an easier way to do this, plz lmk. Thank you.
This is my page.tsx
tsx
import { createClient } from "@/utils/supabase/server";
import DisplayEmail from "../components/DisplayEmail";
export async function getProfile() {
const supabase = createClient();
const user = await supabase.auth.getUser();
console.log(user);
return user;
}
interface DisplayEmailProps {
user: any;
}
const Home : ({}: DisplayEmailProps) => Promise<JSX.Element> = async ({}) => {
const user1 = await getProfile();
return (
<div>
{user1 && <DisplayEmail user={user1} />}
</div>
);
};
export default Home;
The following is my DisplayEmail component
tsx
"use client"
interface User {
id: string;
aud: string;
role: string;
email: string;
email_confirmed_at: string;
phone: string;
confirmation_sent_at: string;
confirmed_at: string;
last_sign_in_at: string;
app_metadata: object;
user_metadata: object;
identities: Array<any>;
created_at: string;
updated_at: string;
is_anonymous: boolean;
}
interface DisplayEmailProps {
user: User;
}
const DisplayEmail: React.FC<DisplayEmailProps> = ({ user }: DisplayEmailProps) => {
return (
<div>
<h2>User Email</h2>
<p>{user.email}</p>
</div>
);
};
export default DisplayEmail;
Turkish Van
The problem might be laying down here:
It should look like this:
export async function getProfile() {
const supabase = createClient();
const user = await supabase.auth.getUser();
console.log(user);
return user;
}await supabase.auth.getUser() doesn't return the user directly like that, but it returns an object with data property that contains user property.It should look like this:
export async function getProfile() {
const supabase = createClient();
const {data: { user }} = await supabase.auth.getUser();
console.log(user);
return user;
}Just in case You want to take a look, here is the docs for the provided information:
https://supabase.com/docs/reference/javascript/auth-getuser
https://supabase.com/docs/reference/javascript/auth-getuser
I think thats definitely a step towards the answer. The email is rendering now but I still have that type error
Type 'User' is not assignable to type '{ id: string; aud: string; role: string; email: string; email_confirmed_at: string; phone: string; confirmation_sent_at: string; confirmed_at: string; last_sign_in_at: string; app_metadata: object; ... 4 more ...; is_anonymous: boolean; }'.
Types of property 'role' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
displayEmail.tsx(4, 7): The expected type comes from property 'user' which is declared here on type 'IntrinsicAttributes & DisplayEmailProps'@evandabest txt
Type 'User' is not assignable to type '{ id: string; aud: string; role: string; email: string; email_confirmed_at: string; phone: string; confirmation_sent_at: string; confirmed_at: string; last_sign_in_at: string; app_metadata: object; ... 4 more ...; is_anonymous: boolean; }'.
Types of property 'role' are incompatible.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
displayEmail.tsx(4, 7): The expected type comes from property 'user' which is declared here on type 'IntrinsicAttributes & DisplayEmailProps'
Turkish Van
Your predefined type
User does not suits the actual type of user object returned from Supabase.Turkish Van
Here is the corrected
User type that seems to be working for me:type User = {
aud: string | null;
banned_until?: string | null;
confirmation_sent_at?: string | null;
confirmation_token?: string | null;
confirmed_at?: string | null;
created_at: string | null;
deleted_at?: string | null;
email?: string | null;
email_change?: string | null;
email_change_confirm_status?: number | null;
email_change_sent_at?: string | null;
email_change_token_current?: string | null;
email_change_token_new?: string | null;
email_confirmed_at?: string | null;
encrypted_password?: string | null;
id: string;
instance_id?: string | null;
invited_at?: string | null;
is_anonymous?: boolean;
is_sso_user?: boolean;
is_super_admin?: boolean | null;
last_sign_in_at?: string | null;
phone?: string | null;
phone_change?: string | null;
phone_change_sent_at?: string | null;
phone_change_token?: string | null;
phone_confirmed_at?: string | null;
raw_app_meta_data?: JSON | null;
raw_user_meta_data?: JSON | null;
reauthentication_sent_at?: string | null;
reauthentication_token?: string | null;
recovery_sent_at?: string | null;
recovery_token?: string | null;
role?: string | null;
updated_at?: string | null;
};Answer
Turkish Van
^
Be careful with
Also some of the fields that are marked as optional might be supposed to never be accessible because of the security reasons. There is an also an
Be careful with
raw_app_meta_data and raw_user_meta_data fields. They might be type of object and not JSON.Also some of the fields that are marked as optional might be supposed to never be accessible because of the security reasons. There is an also an
admin type of client which might be returning the same user object, but with some extra fields mentioned above that the client You use, does not return.Thank you so much
That looks insane though, doesn’t supabase export some type for you to consume?
@evandabest Thank you so much
Turkish Van
Glad to help!
No way they expect users to just type all this out
@joulev That looks insane though, doesn’t supabase export some type for you to consume?
Turkish Van
Yes, they do!
I might be wrong but those types, they export, are primarily supposed to be used for
There is also a way to export these types of types, that are part of
I might be wrong but those types, they export, are primarily supposed to be used for
public tables, tables that You create, and it is all documented inside of Supabase usage documentation.There is also a way to export these types of types, that are part of
auth tables where the above-mentioned type User comes from, but it takes some of the adjustments because of the reason stated above (difference between the clients).Oh good to know. I don’t use supabase at all, don’t know any of this, but I certainly don’t expect libraries to force developers to painstakingly write every line of that big interface
@joulev Oh good to know. I don’t use supabase at all, don’t know any of this, but I certainly don’t expect libraries to force developers to painstakingly write every line of that big interface
Turkish Van
Just in case You are interested in and want to dive deeper into it, here are docs for it:
https://supabase.com/docs/guides/api/rest/generating-types
https://supabase.com/docs/guides/api/rest/generating-types
@Turkish Van Just in case You are interested in and want to dive deeper into it, here are docs for it:
https://supabase.com/docs/guides/api/rest/generating-types
Typically for cases like this, I just inspect the type definition of the function itself (supabase.auth.getUser) (can be done by cmd/ctrl + click in vscode), see what the name of the return type is. 99% of the time, that same name is exported for developers to use so I will then just do something like import type User from supabase
I completely forgot the way I actually set up to do it
Im just going to use the id and search for a match in the table I hace