code: private FunctionType getCallOrBindSignature(boolean isCall) {
      boolean isBind = !isCall;
      Builder builder =
          builder(registry)
              .withReturnType(isCall ? getReturnType() : getBindReturnType(-1))
              .withTemplateKeys(getTemplateTypeMap().getTemplateKeys());
  
      Node origParams = getParametersNode();
      if (origParams != null) {
        Node params = origParams.cloneTree();
  
        Node thisTypeNode = Node.newString(Token.NAME, "thisType");
        thisTypeNode.setJSType(registry.createOptionalNullableType(getTypeOfThis()));
        params.addChildToFront(thisTypeNode);
  
        if (isBind) {
          // The arguments of bind() are unique in that they are all
          // optional but not undefinable.
          for (Node current = thisTypeNode.getNext(); current != null; current = current.getNext()) {
            current.setOptionalArg(true);
          }
        } else if (isCall) {
          // The first argument of call() is optional iff all the arguments
          // are optional. It's sufficient to check the first argument.
          Node firstArg = thisTypeNode.getNext();
          if (firstArg == null || firstArg.isOptionalArg() || firstArg.isVarArgs()) {
            thisTypeNode.setOptionalArg(true);
          }
        }
  
        builder.withParamsNode(params);
      }
  
      return builder.build();
    }
docs: Notice that "call" and "bind" have the same argument signature, except that all the arguments
  of "bind" (except the first) are optional.