GraphQL\Utils\TypeInfo::isTypeSubTypeOf PHP Method

isTypeSubTypeOf() static public method

Provided a type and a super type, return true if the first type is either equal or a subset of the second super type (covariant).
static public isTypeSubTypeOf ( Schema $schema, Type $maybeSubType, Type $superType )
$schema GraphQL\Schema
$maybeSubType GraphQL\Type\Definition\Type
$superType GraphQL\Type\Definition\Type
    static function isTypeSubTypeOf(Schema $schema, Type $maybeSubType, Type $superType)
    {
        // Equivalent type is a valid subtype
        if ($maybeSubType === $superType) {
            return true;
        }
        // If superType is non-null, maybeSubType must also be nullable.
        if ($superType instanceof NonNull) {
            if ($maybeSubType instanceof NonNull) {
                return self::isTypeSubTypeOf($schema, $maybeSubType->getWrappedType(), $superType->getWrappedType());
            }
            return false;
        } else {
            if ($maybeSubType instanceof NonNull) {
                // If superType is nullable, maybeSubType may be non-null.
                return self::isTypeSubTypeOf($schema, $maybeSubType->getWrappedType(), $superType);
            }
        }
        // If superType type is a list, maybeSubType type must also be a list.
        if ($superType instanceof ListOfType) {
            if ($maybeSubType instanceof ListOfType) {
                return self::isTypeSubTypeOf($schema, $maybeSubType->getWrappedType(), $superType->getWrappedType());
            }
            return false;
        } else {
            if ($maybeSubType instanceof ListOfType) {
                // If superType is not a list, maybeSubType must also be not a list.
                return false;
            }
        }
        // If superType type is an abstract type, maybeSubType type may be a currently
        // possible object type.
        if (Type::isAbstractType($superType) && $maybeSubType instanceof ObjectType && $schema->isPossibleType($superType, $maybeSubType)) {
            return true;
        }
        // Otherwise, the child type is not a valid subtype of the parent type.
        return false;
    }

Usage Example

 public function __invoke(ValidationContext $context)
 {
     return [NodeKind::OPERATION_DEFINITION => ['enter' => function () {
         $this->varDefMap = [];
     }, 'leave' => function (OperationDefinitionNode $operation) use($context) {
         $usages = $context->getRecursiveVariableUsages($operation);
         foreach ($usages as $usage) {
             $node = $usage['node'];
             $type = $usage['type'];
             $varName = $node->name->value;
             $varDef = isset($this->varDefMap[$varName]) ? $this->varDefMap[$varName] : null;
             if ($varDef && $type) {
                 // A var type is allowed if it is the same or more strict (e.g. is
                 // a subtype of) than the expected type. It can be more strict if
                 // the variable type is non-null when the expected type is nullable.
                 // If both are list types, the variable item type can be more strict
                 // than the expected item type (contravariant).
                 $schema = $context->getSchema();
                 $varType = TypeInfo::typeFromAST($schema, $varDef->type);
                 if ($varType && !TypeInfo::isTypeSubTypeOf($schema, $this->effectiveType($varType, $varDef), $type)) {
                     $context->reportError(new Error(self::badVarPosMessage($varName, $varType, $type), [$varDef, $node]));
                 }
             }
         }
     }], NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $varDefNode) {
         $this->varDefMap[$varDefNode->variable->name->value] = $varDefNode;
     }];
 }
All Usage Examples Of GraphQL\Utils\TypeInfo::isTypeSubTypeOf