Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
98 views
in Technique[技术] by (71.8m points)

node.js - Typescript - Function return type if I want to return object

Note: Please read through before answering. It looks like a simple question but I'm not sure if it is that simple. Plus I'm new to typescript so go easy on me :p

So here is the use case. I have a model user and I wrote a generic function to check if the user exist based on the email in the DB or not. If it exist it returns the user object.

Now if it would have been any other object then I could have defined the type and carry on with my code but it's the user object I'm getting from DB, not sure how to solve this problem.

I have found the work around for it by mentioning the return type "any" but my soul is not at peace with it. This feels more like a hack than a solution.

Enough talking, here's the code:

export const existingUser = async (email: string): Promise<any> => {
  const foundUser = await User.findOne({ email: email });
  return foundUser;
};

Now as I mentioned above this works, but I tried one different way which was throwing error. I have defined my user model types shown below:

export interface Iuser extends Document {
  profile_picture_url?: string;
  first_name: string;
  last_name: string;
  email: string;
  password: string;
  phone_number?: string;
  is_agree_terms_at: string;
  gender?: Gender;
  role: UserRole;
  isValid: boolean;
}

and then mentioned the Iuser as my return type because that's the type of object I was expecting from the DB. I know it will have other fields once it is added in DB but I don't know any better -_-

export const existingUser = async (email: string): Promise<Iuser> => {
  const foundUser = await User.findOne({ email: email });
  return foundUser;
};

Please help me out. I'm not able to sleep.

question from:https://stackoverflow.com/questions/65919835/typescript-function-return-type-if-i-want-to-return-object

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First problem- Your function is async, it returns a promise, so you need to wrap Iuser inside a promise type-

// NOTE: This code doesn't work just yet, there are more issues
export const existingUser = async (email: string): Promise<Iuser> => {
  const foundUser = await User.findOne({ email: email });
  return foundUser;
};

Second and main problem - If you check the return type of .findOne - you'll notice it returns a union type - Either the document that it found or null (in case your query does not match anything).

This means the type of foundUser is really, Iuser | null, but you're treating it as Iuser - which is not compatible.

What you can do instead is-

export const existingUser = async (email: string): Promise<Iuser | null> => {
  const foundUser = await User.findOne({ email: email });
  return foundUser;
};

Which will also return either Iuser | null.

Or if you're 100% certain the user must exist-

export const existingUser = async (email: string): Promise<Iuser> => {
  const foundUser = await User.findOne({ email: email });
  return foundUser!;
};

The ! operator asserts the type is not null.

Or, if you'd like throw an exception when the user is not found-

export const existingUser = async (email: string): Promise<Iuser> => {
  const foundUser = await User.findOne({ email: email });
  if (!foundUser) {
      throw new Error('User not found');
  }
  return foundUser;
};

Check out using mongoose with typescript to get a general understanding about how to bake your Iuser type directly into your mongoose model - which will let the type system do all the type inferring work for you in this case.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...