打字稿创建有错误的打字卫

时间:2019-02-23 12:44:55

标签: typescript typeguards

type LoggedContext = Required<ApolloContext>;
function authMiddleware(context: ApolloContext): context is LoggedContext {
  if (!context.user) {
    throw new AuthenticationError("Resolver requires login");
  }

  return true;
}

然后像这样使用它:

async user(_, { id }, context) {
    authMiddleware(context);

    const user = context.user;
    // expect typescript to infer that user is defined and not null
  },

有什么方法可以帮助打字稿推断正确的类型?即知道中间件执行后的代码是否被“记录”?

基本上,目标是不必将authMiddleware(context)放入if检查中。

1 个答案:

答案 0 :(得分:1)

您似乎想要type assertion at block-scope level之类的东西,它不是TypeScript功能(从3.3版本开始)。如果它特别引人注目且尚未被提及,则您可能想转到该GitHub问题并为其提供一个或描述您的用例。因此,到目前为止,如果不进行if检查,就无法使用类型保护明确地缩小变量的类型。

您能做什么呢?在这种情况下,我通常要做的是用返回缩小对象的函数替换类型保护,因此,不用x is T,而只需返回T

function authMiddleware(context: ApolloContext): LoggedContext {
  if (!context.user) {
    throw new AuthenticationError("Resolver requires login");
  }
  // the following assertion is equivalent to the type guard returning true
  return context as LoggedContext;
}

现在,当您使用此功能时,对于所有后续引用,请使用返回值代替原始参数:

const aContext = authMiddleware(context);
// use aContext instead of context from now on:

const user = aContext.user; // string

也许会对您有所帮助或为您提供一些有关如何进行的想法。祝你好运!