You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript报错:Type 'null'无法赋值给SetStateAction<string>的解决方法

修复TypeScript中Firebase登录的类型错误

问题场景

将JavaScript版的React Firebase登录代码转为TypeScript后,VS Code抛出了类型不匹配的错误,源代码如下:

import React, { useEffect, useState } from 'react';
import './output.css'; // Adjust path if necessary
import {auth, provider} from './config' ;
import { signInWithPopup } from 'firebase/auth';
import Home from './Home';

function SignIn(){

  const [value,setValue] = useState('')
  const handleClick = () => {
    signInWithPopup(auth, provider).then((data) => {
      setValue(data.user.email)
      localStorage.setItem("email", data.user.email)
    })
  }

  useEffect(() => {
    setValue(localStorage.getItem('email'))
  })

return (
  <div>
  {value?<Home/>:
    <button onClick={handleClick} className='px-2 bg-blue-600 text-white hover:bg-blue-900 pt-2 pb-2 pl-3 pr-3 rounded-md'>Sign in with Google</button>
  }
  </div>
);
}
export default SignIn;

错误信息

  1. 第12行data.user.email:类型string | null无法赋值给类型SetStateAction<string>,Type null无法赋值给类型SetStateAction<string>。ts(2345)
  2. 第12行data.user.email:类型string | null无法赋值给类型string,Type null无法赋值给类型string。ts(2345)
  3. 第18行localStorage.getItem('email'):类型string | null无法赋值给类型SetStateAction<string>,Type null无法赋值给类型SetStateAction<string>。ts(2345)

修复方案

这些错误的核心原因是TypeScript的严格类型检查:Firebase的User.email和localStorage.getItem()都可能返回null,但你的value状态被初始化为空字符串(类型为string),不接受null值。可以通过以下方式修复:

1. 处理空值并确保类型匹配

使用空值合并运算符(??)为可能为null的值提供默认空字符串,同时修正useEffect的依赖数组避免无限循环:

const handleClick = () => {
  signInWithPopup(auth, provider).then((data) => {
    // 给可能为null的email设置默认空字符串
    const userEmail = data.user.email ?? '';
    setValue(userEmail);
    localStorage.setItem("email", userEmail);
  })
}

useEffect(() => {
  // 处理localStorage返回的null值
  setValue(localStorage.getItem('email') ?? '');
}, []) // 添加空依赖数组,仅在组件挂载时执行一次

2. 调整状态类型(可选)

如果希望状态允许null值,可以显式声明状态类型为string | null,这样setValue能直接接受null:

const [value, setValue] = useState<string | null>('');

这种方式更贴合“未登录时无邮箱”的实际场景,后续判断逻辑不需要额外调整。

完整修正后的代码

import React, { useEffect, useState } from 'react';
import './output.css'; // Adjust path if necessary
import { auth, provider } from './config';
import { signInWithPopup } from 'firebase/auth';
import Home from './Home';

function SignIn() {
  const [value, setValue] = useState<string>('');

  const handleClick = () => {
    signInWithPopup(auth, provider).then((data) => {
      const userEmail = data.user.email ?? '';
      setValue(userEmail);
      localStorage.setItem("email", userEmail);
    });
  };

  useEffect(() => {
    setValue(localStorage.getItem('email') ?? '');
  }, []);

  return (
    <div>
      {value ? <Home /> : (
        <button
          onClick={handleClick}
          className='px-2 bg-blue-600 text-white hover:bg-blue-900 pt-2 pb-2 pl-3 pr-3 rounded-md'
        >
          Sign in with Google
        </button>
      )}
    </div>
  );
}

export default SignIn;

额外说明

如果确定Google登录后的用户一定有邮箱,也可以用非空断言运算符(!)强制告知TypeScript值不为null,但这种方式不推荐——若出现异常场景(比如用户账号无邮箱)会引发运行时错误:

setValue(data.user.email!)
localStorage.setItem("email", data.user.email!)

内容的提问来源于stack exchange,提问作者Jahin Ahnaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:03:19