@@ -402,15 +402,12 @@ private function determineExactType(Type $in, int $filterValue, Type $defaultTyp
402402 new NullType (),
403403 ]);
404404
405- $ scalarOrNullType = null ;
405+ $ scalarOrNullType = $ in ;
406406 $ useDefaultType = false ;
407407
408- if ($ scalarOrNull ->isSuperTypeOf ($ in )->yes ()) {
409- $ scalarOrNullType = $ in ;
410- }
411-
412408 if ($ scalarOrNull ->isSuperTypeOf ($ in )->maybe ()) {
413- // $in is (array or object) or (scalar or null).
409+ // $in is a union of maybe null, maybe scalar, and a non-scalar.
410+ // Force it to a union of maybe null and maybe scalar.
414411 $ scalarOrNullType = TypeCombinator ::remove (
415412 TypeCombinator ::remove ($ in , new ObjectShapeType ([], [])),
416413 new ArrayType (new MixedType (), new MixedType ()),
@@ -419,25 +416,20 @@ private function determineExactType(Type $in, int $filterValue, Type $defaultTyp
419416 $ useDefaultType = true ;
420417 }
421418
422- if (
423- $ scalarOrNullType !== null
424- && ($ in ->isSuperTypeOf (new MixedType ())->yes () || $ scalarOrNull ->isSuperTypeOf ($ scalarOrNullType )->yes ())
425- ) {
426- $ canBeSanitized = $ this ->canStringBeSanitized ($ filterValue , $ flagsType );
427- if ($ canBeSanitized ->no ()) {
428- $ stringType = $ scalarOrNullType ->toString ();
429- } elseif ($ scalarOrNullType ->isString ()->no ()) {
430- $ stringType = $ scalarOrNullType ->toString ();
431- } else {
432- $ stringType = TypeCombinator ::union (
433- TypeCombinator ::remove ($ scalarOrNullType , new StringType ()),
434- new StringType (),
435- );
436- }
437-
438- $ returnType = $ this ->handleEmptyStringNullFlag ($ stringType , $ flagsType );
439- return $ useDefaultType ? TypeCombinator ::union ($ defaultType , $ returnType ) : $ returnType ;
419+ $ canBeSanitized = $ this ->canStringBeSanitized ($ filterValue , $ flagsType );
420+ if ($ canBeSanitized ->no ()) {
421+ $ stringType = $ scalarOrNullType ->toString ();
422+ } elseif ($ scalarOrNullType ->isString ()->no ()) {
423+ $ stringType = $ scalarOrNullType ->toString ();
424+ } else {
425+ $ stringType = TypeCombinator ::union (
426+ TypeCombinator ::remove ($ scalarOrNullType , new StringType ()),
427+ new StringType (),
428+ );
440429 }
430+
431+ $ returnType = $ this ->handleEmptyStringNullFlag ($ stringType , $ flagsType );
432+ return $ useDefaultType ? TypeCombinator ::union ($ defaultType , $ returnType ) : $ returnType ;
441433 }
442434
443435 return null ;
@@ -450,12 +442,19 @@ private function handleEmptyStringNullFlag(Type $in, ?Type $flagsType): Type
450442 return $ in ;
451443 }
452444
453- $ hasEmptyString = !$ in ->isSuperTypeOf (new ConstantStringType ('' ))->no ();
454445 if ($ hasFlag ->maybe ()) {
455- return $ hasEmptyString ? TypeCombinator ::addNull ($ in ) : $ in ;
446+ return $ in ->isNonEmptyString ()->maybe () ? TypeCombinator ::addNull ($ in ) : $ in ;
447+ }
448+
449+ if ($ in ->isNonEmptyString ()->yes ()) {
450+ return $ in ;
451+ }
452+
453+ if ($ in ->isNonEmptyString ()->maybe ()) {
454+ return TypeCombinator ::remove (TypeCombinator ::addNull ($ in ), new ConstantStringType ('' ));
456455 }
457456
458- return $ hasEmptyString ? TypeCombinator :: remove ( TypeCombinator :: addNull ( $ in ), new ConstantStringType ( '' )) : $ in ;
457+ return new NullType () ;
459458 }
460459
461460 /** @param array<string, ?Type> $typeOptions */
0 commit comments