You can write your own converter as described in Firestore documentation.
firebase.firestore.FirestoreDataConverter<T> - Converter used by withConverter() to transform user objects of type T into Firestore data.
Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore.
class Post {
  constructor(readonly title: string, readonly author: string) {}
  toString(): string {
    return this.title + ', by ' + this.author;
  }
}
const postConverter = {
  toFirestore(post: Post): firebase.firestore.DocumentData {
    return {title: post.title, author: post.author};
  },
  fromFirestore(
    snapshot: firebase.firestore.QueryDocumentSnapshot,
    options: firebase.firestore.SnapshotOptions
  ): Post {
    const data = snapshot.data(options)!;
    return new Post(data.title, data.author);
  }
};
const postSnap = await firebase.firestore()
  .collection('posts')
  .withConverter(postConverter)
  .doc().get();
const post = postSnap.data();
if (post !== undefined) {
  post.title; // string
  post.toString(); // Should be defined
  post.someNonExistentProperty; // TS error
}