首页 > 解决方案 > 当属性是 useContext 挂钩的函数类型时的 TypeScript 接口默认值

问题描述

我刚开始使用 Typescript。我看到了很多关于自定义钩子的示例和问题,但由于我的文件结构与其他示例不同,我仍然无法弄清楚。

背景:

我有这个名为 1 的文件useAuth.tsx,其结构如下:

const defaultValue = { // Here I make this temporary 1st 
  
};

const AuthContext = createContext(defaultValue)

const AuthContextProvider = (props: AuthContextProviderProps) => {
  const auth = useFirebaseAuth(); // this will use value from the hook below

  return (
    <AuthContext.Provider value={auth}>{props.children}</AuthContext.Provider>
  );
};

export default function useFirebaseAuth() {
  const [user, setUser] = useState<UserDetails | null>(null);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);

  const loginWithEmailPassword = (email: string, password: string) => {
    //... stuff
  }

  const signUpWithEmailPassword = (email: string, password: string) => {
    //... stuff
  }

  return {
    user,
    isLoading,
    errorMessage,
    loginWithEmailPassword,
    signUpWithEmailPassword,
  };

}

**Problems:** 

所以当我useAuth()在另一个文件中使用这个钩子时,命名Login.tsx如下:

const { user } = useAuth(); 

我会收到这个错误:

Property 'user' does not exist on type '{}'.ts(2339)

我的尝试:

据我了解,问题是由于user未在 中定义useAuth(),因此 TypeScript 不知道user内部存在useAuth

这是我尝试过的:

interface UserData {
 id: ... //etc 

}

// here define an interface for all the return value 
interface AuthContextInterface {  
  user: UserData | null;
  loginWithEmailPassword: (email: string, password: string )=> void;
  signUpWithEmailPassword: (email: string, password: string )=> void;
  isLoading: boolean;
  errorMessage: string | null;
}


// then use it here as  a type of createContext 
const AuthContext = createContext<AuthContextInterface>(defaultValue)

此时我将在以下位置遇到此问题defaultValue

Type '{}' is missing the following properties from type 'AuthContextInterface': user, loginWithEmailPassword, signUpWithEmailPassword, isLoading, errorMessage

所以我也必须定义里面的值defaultValue

const defaultValue = {
  
  user:null,
  isLoading: false,
  errorMessage: null,
  
  loginWithEmailPassword:() => void, // this is the problem, what should I put here as default value 
  signUpWithEmailPassword: () => void, 
};

Others value 没有问题,但是loginWithEmailPasswordandsignUpWithEmailPassword是一个函数,所以作为默认值我应该说什么,因为它还不存在?

请给一些建议。时间

标签: reactjstypescriptreact-hooks

解决方案


尝试为 defaultValue 定义一个空对象:

const defaultValue = {};

并创建强制打字稿将默认值理解为接口的上下文

const AuthContext = createContext<AuthContextInterface>(defaultValue as AuthContextInterface);

如果你不使用 eslint,你也可以这样做

const AuthContext = createContext<AuthContextInterface>(defaultValue as any);

推荐阅读