Arsh Sharma
Arsh Sharma

Reputation: 1331

Property not exsisting on a type in React with TypeScript

I am creating a chatbox and for the send message functionality I have the following code:

function ChatRoom() {
  const messagesRef = firestore.collection('messages');
  const query = messagesRef.orderBy('createdAt').limit(25);

  const [messages] = useCollectionData(query, { idField: 'id' });
  const [formValue, setFormValue] = useState('');
  const sendMessage = async (e: any) => {
    e.preventDefault();

    const { uid, photoURL } = auth.currentUser;

    await messagesRef.add({
      text: formValue,
      createdAt: firebase.firestore.FieldValue.serverTimestamp(),
      uid,
      photoURL,
    });

    setFormValue('');
  };
  console.log(messages);
  console.log(auth.currentUser);
  return (
    <>
      <div>
        {messages &&
          messages.map(msg => (
            <ChatMessage key={(msg as Message).id} message={msg} />
          ))}
      </div>
      <form onSubmit={sendMessage}>
        <input
          value={formValue}
          onChange={e => setFormValue(e.target.value)}
          placeholder='say something nice'
        />

        <button type='submit' disabled={!formValue}>
          🕊️
        </button>
      </form>
    </>
  );
}

Here I am getting the error: Property 'uid' does not exist on type 'User | null'. and Property 'photoURL' does not exist on type 'User | null'. Now I get that I have to define an interface and do this. But two problems arise here.

  1. How do I make the interface. I console logged auth.currentUser and it is a pretty big object with loads of stuff (using Firebase).

enter image description here

  1. If I do create an interface how do I assign it? Doing something like: const { uid, photoURL } = (auth.currentUser : User); still gives an error where User is the name of my interface.

I am new to TypeScript with React and any would be glad if someone could point me in the right direction. Much thanks.

Upvotes: 0

Views: 475

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42298

Here I am getting the error: Property 'uid' does not exist on type 'User | null'. and Property 'photoURL' does not exist on type 'User | null'. Now I get that I have to define an interface and do this.

You are thinking that you need to define an interface because your component doesn't know the type of auth.currentUser. But that is not how that error message reads to me. Typescript believes that the type of auth.currentUser is User | null. So there is already a User type or interface, which presumably has a whole bunch of properties and probably already defines uid and photoURL. That's not the issue. The issue is the | null part. auth.currentUser is either a User object representing the current user, or it's null. You can't destructure it until you know that it's an object and not null. That is what the error is saying.

So we need to check the value and make sure that we don't have null:

const sendMessage = async (e: any) => {
  e.preventDefault();

  const user = auth.currentUser;

  if (user) {
    const { uid, photoURL } = user;

    await messagesRef.add({
      text: formValue,
      createdAt: firebase.firestore.FieldValue.serverTimestamp(),
      uid,
      photoURL,
    });

    setFormValue('');
    
  } else {
    // can handle error somehow
  }
};

Upvotes: 5

Related Questions