Repository: babel/babel
File: packages/babel-traverse/src/path/inference/inferer-reference.ts (TypeScript)

Code before:
    typeofPath = right;
    typePath = left as NodePath<t.Expression>;
  }

  if (!typeofPath!) return;
  // and that the argument of the typeof path references us!
  if (!typeofPath.get("argument").isIdentifier({ name })) return;

  // ensure that the type path is a Literal
  typePath = typePath!.resolve() as NodePath<t.Expression>;
  if (!typePath.isLiteral()) return;

  // and that it's a string so we can infer it
  // @ts-expect-error todo(flow->ts): value is not defined for NullLiteral and some other
  const typeValue = typePath.node.value;
  if (typeof typeValue !== "string") return;

  // turn type value into a type annotation
  // @ts-expect-error todo(flow->ts): move validation from helper or relax type constraint to just a string
  return createTypeAnnotationBasedOnTypeof(typeValue);
}

function getParentConditionalPath(
  binding: Binding,
  path: NodePath,
  name: string | undefined,
) {
  let parentPath;
  while ((parentPath = path.parentPath)) {
    if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {
      if (path.key === "test") {
        return;
      }

      return parentPath as NodePath<t.IfStatement | t.ConditionalExpression>;
    }
    if (parentPath.isFunction()) {
      if (
        name == null ||
        parentPath.parentPath.scope.getBinding(name) !== binding
      )
        return;
    }

    path = parentPath;
  }
}

function getConditionalAnnotation<T extends t.Node>(
  binding: Binding,
  path: NodePath<T>,

Review comment (suggestion):
The `name` here is passed from a `name` property of an `Identifier`, I think it should be always a string unless the AST is malformed.

https://github.com/babel/babel/blob/c36fa6a9299df95b801695736f78ac87211f009f/packages/babel-traverse/src/path/inference/inferer-reference.ts#L23

https://github.com/babel/babel/blob/c36fa6a9299df95b801695736f78ac87211f009f/packages/babel-traverse/src/path/inference/inferer-reference.ts#L55

Can we remove the `optional` marker here?

https://github.com/babel/babel/blob/c36fa6a9299df95b801695736f78ac87211f009f/packages/babel-traverse/src/path/inference/inferer-reference.ts#L211

Code after:
    typeofPath = right;
    typePath = left as NodePath<t.Expression>;
  }

  if (!typeofPath!) return;
  // and that the argument of the typeof path references us!
  if (!typeofPath.get("argument").isIdentifier({ name })) return;

  // ensure that the type path is a Literal
  typePath = typePath!.resolve() as NodePath<t.Expression>;
  if (!typePath.isLiteral()) return;

  // and that it's a string so we can infer it
  // @ts-expect-error todo(flow->ts): value is not defined for NullLiteral and some other
  const typeValue = typePath.node.value;
  if (typeof typeValue !== "string") return;

  // turn type value into a type annotation
  // @ts-expect-error todo(flow->ts): move validation from helper or relax type constraint to just a string
  return createTypeAnnotationBasedOnTypeof(typeValue);
}

function getParentConditionalPath(
  binding: Binding,
  path: NodePath,
  name: string,
) {
  let parentPath;
  while ((parentPath = path.parentPath)) {
    if (parentPath.isIfStatement() || parentPath.isConditionalExpression()) {
      if (path.key === "test") {
        return;
      }

      return parentPath as NodePath<t.IfStatement | t.ConditionalExpression>;
    }
    if (parentPath.isFunction()) {
      if (
        name == null ||
        parentPath.parentPath.scope.getBinding(name) !== binding
      )
        return;
    }

    path = parentPath;
  }
}

function getConditionalAnnotation<T extends t.Node>(
  binding: Binding,
  path: NodePath<T>,