Typescript - 如果我想返回对象,函数返回类型

Posted

技术标签:

【中文标题】Typescript - 如果我想返回对象,函数返回类型【英文标题】:Typescript - Function return type if I want to return object 【发布时间】:2021-05-01 07:52:46 【问题描述】:

注意:请在回答前通读。这看起来像一个简单的问题,但我不确定它是否那么简单。另外,我是打字稿的新手,所以请放轻松:p

所以这是用例。我有一个模型用户,我编写了一个通用函数来根据数据库中的电子邮件检查用户是否存在。如果存在,则返回用户对象。

现在,如果它是任何其他对象,那么我可以定义类型并继续执行我的代码,但它是我从 DB 获取的用户对象,不知道如何解决这个问题。

我通过提到返回类型“any”找到了解决它的方法,但我的灵魂对此并不平静。这感觉更像是一种 hack,而不是一种解决方案。

废话不多说,代码如下:

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

现在,正如我上面提到的,这可行,但我尝试了一种不同的方法,即抛出错误。我已经定义了如下所示的用户模型类型:

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;

然后提到 Iuser 作为我的返回类型,因为这是我期望从数据库中获得的对象类型。我知道一旦添加到数据库中它会有其他字段,但我不知道更好-_-

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

请帮帮我。我睡不着。

【问题讨论】:

你能更新错误吗?另外,请在扩展文档界面时更新文档界面以及您的架构如何查找用户? 【参考方案1】:

第一个问题-你的函数是async,它返回一个promise,所以你需要将Iuser包装在一个promise类型中-

// 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;
;

第二个也是主要问题 - 如果您检查 .findOne 的返回类型 - 您会注意到它返回联合类型 - 它找到的文档 null(如果您的查询不匹配任何内容)。

这意味着foundUser 的类型实际上是Iuser | null,但您将其视为Iuser - 这是不兼容的。

你可以做的是-

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

这也将返回Iuser | null

或者,如果您100% 确定用户必须存在-

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

! operator 断言类型是not null

或者,如果您想在找不到用户时抛出异常-

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;
;

查看using mongoose with typescript 以大致了解如何将您的Iuser 类型直接烘焙到您的猫鼬模型中——这将使类型系统在这种情况下为您完成所有类型推断工作。

【讨论】:

我在返回类型中没有提到承诺,这很糟糕。我已经更新了这个问题。感谢您的回答,这完全有道理。欢呼

以上是关于Typescript - 如果我想返回对象,函数返回类型的主要内容,如果未能解决你的问题,请参考以下文章

返回具有额外属性的 arg 的 TypeScript 函数 (TS2322)

Typescript从参数返回函数类型

使用 TypeScript 函数返回 JSON 对象

Typescript 无法检查函数返回类型的嵌套对象

用 Jest 和 Typescript 模拟一个全局对象

TypeScript - 传递给构造函数整个对象