Auth Context在类型方面存在一些问题。

13 浏览
0 Comments

Auth Context在类型方面存在一些问题。

虽然我是用这个教程(链接到具体的认证上下文文件)创建的代码,但它并不起作用。这个片段特别是认证上下文的一部分。唯一的区别是我使用TypeScript而不是JavaScript编码。告诉我是否还需要其他任何帮助来解决我的问题。\n错误:\n

src/contexts/AuthContext.tsx:76:46
TS2339: 类型“Promise”上不存在属性“user”。
    74 |
    75 |     useEffect(() => {
  > 76 |         const user = supabase.auth.getUser().user;
       |                                              ^^^^
    77 |         setCurrentUser(user)
    78 |
    79 |         const auth = supabase.auth.onAuthStateChange((event, session) => {
src/contexts/AuthContext.tsx:81:32
TS2531: 对象可能为“null”。
    79 |         const auth = supabase.auth.onAuthStateChange((event, session) => {
    80 |             if (event === 'SIGNED_IN') {
  > 81 |                 setCurrentUser(session.user)
       |                                ^^^^^^^
    82 |             }
    83 |
    84 |             if (event === 'SIGNED_OUT') {
src/contexts/AuthContext.tsx:81:32
TS2345: 类型“User”的参数不能赋给类型“SetStateAction”的参数。
  类型“User”无法为“(prevState: undefined) => undefined”的签名提供匹配项。
    79 |         const auth = supabase.auth.onAuthStateChange((event, session) => {
    80 |             if (event === 'SIGNED_IN') {
  > 81 |                 setCurrentUser(session.user)
       |                                ^^^^^^^^^^^^
    82 |             }
    83 |
    84 |             if (event === 'SIGNED_OUT') {
src/contexts/AuthContext.tsx:85:32
TS2345: 类型“null”的参数不能赋给类型“SetStateAction”的参数。
    83 |
    84 |             if (event === 'SIGNED_OUT') {
  > 85 |                 setCurrentUser(null)
       |                                ^^^^
    86 |             }
    87 |         })
    88 |
src/contexts/AuthContext.tsx:89:32
TS2339: 类型“{ subscription: Subscription; }”上不存在属性“unsubscribe”。
    87 |         })
    88 |
  > 89 |         return () => auth.data.unsubscribe()
       |                                ^^^^^^^^^^^
    90 |
    91 |     }, [])
    92 |

\n提前感谢您的帮助。

0
0 Comments

Supabase v.0.0+版本中的auth函数和它们的返回类型发生了一些变化。不再提供supabase.auth.user()函数,只提供了可Promise化的supabase.auth.getUser()函数。getUser的返回类型为

export type UserResponse =
  | {
      data: {
        user: User
      }
      error: null
    }
  | {
      data: {
        user: null
      }
      error: AuthError
    }

我认为对象解构更可读,所以更推荐使用

const { data: { user } = await supabase.auth.getUser()

这也解决了onAuthStateChange()的返回问题,返回类型为

{
  data: { subscription: Subscription }
}

所以您的代码将变成

const { data: { subscription }} = supabase.auth.onAuthStateChange(callback);

Supabase v.0.0+版本提供了两个获取用户信息的函数,.user().getUser().user()从localStorage中获取用户信息,这意味着它是一个非Promise函数。 .getUser()使用jwt从服务器获取用户信息,因此是一个Promise。在教程中,他们使用了.user()函数,这就是为什么没有使用await的原因。在您的代码中,您使用了.getUser()函数。要继续在useEffect中使用.getUser()函数,您必须在async函数中调用它。

要解决useState的错误,当状态的类型与传递给useState()函数的defaultValue的类型不同时,必须向useState()函数传递一个类型。

解决这个问题的方法是向useState传递User类型:

import { User } from '/supabase-js';
const [currentUser, setCurrentUser] = useState<User | null>(null);

要解决'Object could be null'错误,您只需添加一个nullish检查,可以通过if/else语句或添加nullish变量检查来实现。

在if/else语句中添加nullish检查:

if(user) 或 if(user !== null) {
  setCurrentUser(user)
}

或者添加nullish变量检查:

const user = session?.user;

在!user和user !== null之间存在一些细微的差别,后者的范围更小。supabase和typescript的文档都是很好的资源。

如果您没有特殊的需求来创建自己的supabase身份验证系统,我建议使用supabase-auth-helpers。

0