diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php
index a5dc7bc6a5..fb8b5985e7 100644
--- a/src/Analyser/TypeSpecifier.php
+++ b/src/Analyser/TypeSpecifier.php
@@ -28,6 +28,7 @@
 use PHPStan\Reflection\ParametersAcceptorWithPhpDocs;
 use PHPStan\Reflection\ReflectionProvider;
 use PHPStan\Reflection\ResolvedFunctionVariant;
+use PHPStan\Rules\Arrays\AllowedArrayKeysTypes;
 use PHPStan\ShouldNotHappenException;
 use PHPStan\TrinaryLogic;
 use PHPStan\Type\Accessory\AccessoryArrayListType;
@@ -820,47 +821,8 @@ public function specifyTypesInCondition(
 						);
 					} else {
 						$varType = $scope->getType($var->var);
-						if ($varType->isArray()->yes() && !$varType->isIterableAtLeastOnce()->no()) {
-							$varIterableKeyType = $varType->getIterableKeyType();
-
-							if ($varIterableKeyType->isConstantScalarValue()->yes()) {
-								$narrowedKey = TypeCombinator::union(
-									$varIterableKeyType,
-									TypeCombinator::remove($varIterableKeyType->toString(), new ConstantStringType('')),
-								);
-
-								if (!$varType->hasOffsetValueType(new ConstantIntegerType(0))->no()) {
-									$narrowedKey = TypeCombinator::union(
-										$narrowedKey,
-										new ConstantBooleanType(false),
-									);
-								}
-
-								if (!$varType->hasOffsetValueType(new ConstantIntegerType(1))->no()) {
-									$narrowedKey = TypeCombinator::union(
-										$narrowedKey,
-										new ConstantBooleanType(true),
-									);
-								}
-
-								if (!$varType->hasOffsetValueType(new ConstantStringType(''))->no()) {
-									$narrowedKey = TypeCombinator::addNull($narrowedKey);
-								}
-
-								if (!$varIterableKeyType->isNumericString()->no() || !$varIterableKeyType->isInteger()->no()) {
-									$narrowedKey = TypeCombinator::union($narrowedKey, new FloatType());
-								}
-							} else {
-								$narrowedKey = new MixedType(
-									false,
-									new UnionType([
-										new ArrayType(new MixedType(), new MixedType()),
-										new ObjectWithoutClassType(),
-										new ResourceType(),
-									]),
-								);
-							}
-
+						$narrowedKey = AllowedArrayKeysTypes::narrowOffsetKeyType($varType, $dimType);
+						if ($narrowedKey !== null) {
 							$types = $types->unionWith(
 								$this->create(
 									$var->dim,
diff --git a/src/Rules/Arrays/AllowedArrayKeysTypes.php b/src/Rules/Arrays/AllowedArrayKeysTypes.php
index 0bc7c1f4c4..2b15a4eb65 100644
--- a/src/Rules/Arrays/AllowedArrayKeysTypes.php
+++ b/src/Rules/Arrays/AllowedArrayKeysTypes.php
@@ -2,12 +2,20 @@
 
 namespace PHPStan\Rules\Arrays;
 
+use PHPStan\Type\ArrayType;
 use PHPStan\Type\BooleanType;
+use PHPStan\Type\Constant\ConstantBooleanType;
+use PHPStan\Type\Constant\ConstantIntegerType;
+use PHPStan\Type\Constant\ConstantStringType;
 use PHPStan\Type\FloatType;
 use PHPStan\Type\IntegerType;
+use PHPStan\Type\MixedType;
 use PHPStan\Type\NullType;
+use PHPStan\Type\ObjectWithoutClassType;
+use PHPStan\Type\ResourceType;
 use PHPStan\Type\StringType;
 use PHPStan\Type\Type;
+use PHPStan\Type\TypeCombinator;
 use PHPStan\Type\UnionType;
 
 final class AllowedArrayKeysTypes
@@ -24,4 +32,55 @@ public static function getType(): Type
 		]);
 	}
 
+	public static function narrowOffsetKeyType(Type $varType, Type $keyType): ?Type
+	{
+		if (!$varType->isArray()->yes() || $varType->isIterableAtLeastOnce()->no()) {
+			return null;
+		}
+
+		$varIterableKeyType = $varType->getIterableKeyType();
+
+		if ($varIterableKeyType->isConstantScalarValue()->yes()) {
+			$narrowedKey = TypeCombinator::union(
+				$varIterableKeyType,
+				TypeCombinator::remove($varIterableKeyType->toString(), new ConstantStringType('')),
+			);
+
+			if (!$varType->hasOffsetValueType(new ConstantIntegerType(0))->no()) {
+				$narrowedKey = TypeCombinator::union(
+					$narrowedKey,
+					new ConstantBooleanType(false),
+				);
+			}
+
+			if (!$varType->hasOffsetValueType(new ConstantIntegerType(1))->no()) {
+				$narrowedKey = TypeCombinator::union(
+					$narrowedKey,
+					new ConstantBooleanType(true),
+				);
+			}
+
+			if (!$varType->hasOffsetValueType(new ConstantStringType(''))->no()) {
+				$narrowedKey = TypeCombinator::addNull($narrowedKey);
+			}
+
+			if (!$varIterableKeyType->isNumericString()->no() || !$varIterableKeyType->isInteger()->no()) {
+				$narrowedKey = TypeCombinator::union($narrowedKey, new FloatType());
+			}
+
+			return $narrowedKey;
+		} elseif ($varIterableKeyType->isInteger()->yes() && $keyType->isString()->yes()) {
+			return TypeCombinator::intersect($varIterableKeyType->toString(), $keyType);
+		}
+
+		return new MixedType(
+			false,
+			new UnionType([
+				new ArrayType(new MixedType(), new MixedType()),
+				new ObjectWithoutClassType(),
+				new ResourceType(),
+			]),
+		);
+	}
+
 }
diff --git a/tests/PHPStan/Analyser/nsrt/bug-11716.php b/tests/PHPStan/Analyser/nsrt/bug-11716.php
index 2394e8a175..e637669483 100644
--- a/tests/PHPStan/Analyser/nsrt/bug-11716.php
+++ b/tests/PHPStan/Analyser/nsrt/bug-11716.php
@@ -35,9 +35,10 @@ public function parse(string $glue): string
 }
 
 /**
- * @param array<int, string> $arr
+ * @param array<int, string> $intKeyedArr
+ * @param array<string, string> $stringKeyedArr
  */
-function narrowKey($mixed, string $s, int $i, array $generalArr, array $arr): void {
+function narrowKey($mixed, string $s, int $i, array $generalArr, array $intKeyedArr, array $stringKeyedArr): void {
 	if (isset($generalArr[$mixed])) {
 		assertType('mixed~(array|object|resource)', $mixed);
 	} else {
@@ -59,21 +60,42 @@ function narrowKey($mixed, string $s, int $i, array $generalArr, array $arr): vo
 	}
 	assertType('string', $s);
 
-	if (isset($arr[$mixed])) {
+	if (isset($intKeyedArr[$mixed])) {
 		assertType('mixed~(array|object|resource)', $mixed);
 	} else {
 		assertType('mixed', $mixed);
 	}
 	assertType('mixed', $mixed);
 
-	if (isset($arr[$i])) {
+	if (isset($intKeyedArr[$i])) {
 		assertType('int', $i);
 	} else {
 		assertType('int', $i);
 	}
 	assertType('int', $i);
 
-	if (isset($arr[$s])) {
+	if (isset($intKeyedArr[$s])) {
+		assertType("numeric-string", $s);
+	} else {
+		assertType('string', $s);
+	}
+	assertType('string', $s);
+
+	if (isset($stringKeyedArr[$mixed])) {
+		assertType('mixed~(array|object|resource)', $mixed);
+	} else {
+		assertType('mixed', $mixed);
+	}
+	assertType('mixed', $mixed);
+
+	if (isset($stringKeyedArr[$i])) {
+		assertType('int', $i);
+	} else {
+		assertType('int', $i);
+	}
+	assertType('int', $i);
+
+	if (isset($stringKeyedArr[$s])) {
 		assertType('string', $s);
 	} else {
 		assertType('string', $s);