diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index a07ea29556..8a84b172f6 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1560,12 +1560,6 @@ parameters:
 			count: 1
 			path: src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.php
 
-		-
-			message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantStringType is error\-prone and deprecated\. Use Type\:\:getConstantStrings\(\) instead\.$#'
-			identifier: phpstanApi.instanceofType
-			count: 2
-			path: src/Type/Php/LtrimFunctionReturnTypeExtension.php
-
 		-
 			message: '#^Doing instanceof PHPStan\\Type\\Constant\\ConstantStringType is error\-prone and deprecated\. Use Type\:\:getConstantStrings\(\) instead\.$#'
 			identifier: phpstanApi.instanceofType
diff --git a/src/Type/Php/LtrimFunctionReturnTypeExtension.php b/src/Type/Php/LtrimFunctionReturnTypeExtension.php
index 701e474fe5..77cd8cbb7b 100644
--- a/src/Type/Php/LtrimFunctionReturnTypeExtension.php
+++ b/src/Type/Php/LtrimFunctionReturnTypeExtension.php
@@ -14,6 +14,7 @@
 use PHPStan\Type\IntersectionType;
 use PHPStan\Type\StringType;
 use PHPStan\Type\Type;
+use PHPStan\Type\TypeCombinator;
 use function count;
 use function ltrim;
 
@@ -53,12 +54,27 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
 
 		$trimChars = $scope->getType($functionCall->getArgs()[1]->value);
 
-		if ($trimChars instanceof ConstantStringType && $trimChars->getValue() === '\\' && $string->isClassString()->yes()) {
-			if ($string instanceof ConstantStringType) {
-				return new ConstantStringType(ltrim($string->getValue(), $trimChars->getValue()), true);
+		$trimConstantStrings = $trimChars->getConstantStrings();
+		if (count($trimConstantStrings) > 0) {
+			$result = [];
+			$stringConstantStrings = $string->getConstantStrings();
+
+			foreach ($trimConstantStrings as $trimConstantString) {
+				if (count($stringConstantStrings) > 0) {
+					foreach ($stringConstantStrings as $stringConstantString) {
+						$result[] = new ConstantStringType(
+							ltrim($stringConstantString->getValue(), $trimConstantString->getValue()),
+							true,
+						);
+					}
+				} elseif ($trimConstantString->getValue() === '\\' && $string->isClassString()->yes()) {
+					$result[] = new ClassStringType();
+				} else {
+					return $defaultType;
+				}
 			}
 
-			return new ClassStringType();
+			return TypeCombinator::union(...$result);
 		}
 
 		return $defaultType;
diff --git a/src/Type/Php/TrimFunctionDynamicReturnTypeExtension.php b/src/Type/Php/TrimFunctionDynamicReturnTypeExtension.php
index 3b6c27320a..3cf845f523 100644
--- a/src/Type/Php/TrimFunctionDynamicReturnTypeExtension.php
+++ b/src/Type/Php/TrimFunctionDynamicReturnTypeExtension.php
@@ -8,12 +8,16 @@
 use PHPStan\Reflection\FunctionReflection;
 use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
 use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
+use PHPStan\Type\Constant\ConstantStringType;
 use PHPStan\Type\DynamicFunctionReturnTypeExtension;
 use PHPStan\Type\IntersectionType;
 use PHPStan\Type\StringType;
 use PHPStan\Type\Type;
+use PHPStan\Type\TypeCombinator;
 use function count;
 use function in_array;
+use function rtrim;
+use function trim;
 
 #[AutowiredService]
 final class TrimFunctionDynamicReturnTypeExtension implements DynamicFunctionReturnTypeExtension
@@ -37,6 +41,7 @@ public function getTypeFromFunctionCall(
 
 		$stringType = $scope->getType($args[0]->value);
 		$accessory = [];
+		$defaultType = new StringType();
 		if ($stringType->isLowercaseString()->yes()) {
 			$accessory[] = new AccessoryLowercaseStringType();
 		}
@@ -45,10 +50,40 @@ public function getTypeFromFunctionCall(
 		}
 		if (count($accessory) > 0) {
 			$accessory[] = new StringType();
-			return new IntersectionType($accessory);
+			$defaultType = new IntersectionType($accessory);
 		}
 
-		return new StringType();
+		if (count($functionCall->getArgs()) !== 2) {
+			return $defaultType;
+		}
+
+		$trimChars = $scope->getType($functionCall->getArgs()[1]->value);
+
+		$trimConstantStrings = $trimChars->getConstantStrings();
+		if (count($trimConstantStrings) > 0) {
+			$result = [];
+			$stringConstantStrings = $stringType->getConstantStrings();
+			$functionName = $functionReflection->getName();
+
+			foreach ($trimConstantStrings as $trimConstantString) {
+				if (count($stringConstantStrings) === 0) {
+					return $defaultType;
+				}
+
+				foreach ($stringConstantStrings as $stringConstantString) {
+					$result[] = new ConstantStringType(
+						$functionName === 'rtrim'
+							? rtrim($stringConstantString->getValue(), $trimConstantString->getValue())
+							: trim($stringConstantString->getValue(), $trimConstantString->getValue()),
+						true,
+					);
+				}
+			}
+
+			return TypeCombinator::union(...$result);
+		}
+
+		return $defaultType;
 	}
 
 }
diff --git a/tests/PHPStan/Analyser/nsrt/trim.php b/tests/PHPStan/Analyser/nsrt/trim.php
new file mode 100644
index 0000000000..51908b0995
--- /dev/null
+++ b/tests/PHPStan/Analyser/nsrt/trim.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace Trim;
+
+use function PHPStan\Testing\assertType;
+
+class Foo
+{
+
+	/**
+	 * @param 'foo' $foo
+	 * @param 'foo'|'bar' $fooOrBar
+	 * @param 'constant'|class-string<Foo> $constantOrFooClass
+	 * @param string $string
+	 */
+	public function doTrim($foo, $fooOrBar, $constantOrFooClass, $string): void
+	{
+		assertType('string', trim($string, $foo));
+		assertType('string', ltrim($string, $foo));
+		assertType('string', rtrim($string, $foo));
+
+		assertType('lowercase-string', trim($foo, $string));
+		assertType('lowercase-string', ltrim($foo, $string));
+		assertType('lowercase-string', rtrim($foo, $string));
+		assertType('\'\'|\'foo\'', trim($foo, $fooOrBar));
+		assertType('\'\'|\'foo\'', ltrim($foo, $fooOrBar));
+		assertType('\'\'|\'foo\'', rtrim($foo, $fooOrBar));
+
+		assertType('lowercase-string', trim($fooOrBar, $string));
+		assertType('lowercase-string', ltrim($fooOrBar, $string));
+		assertType('lowercase-string', rtrim($fooOrBar, $string));
+		assertType('\'\'|\'bar\'', trim($fooOrBar, $foo));
+		assertType('\'\'|\'bar\'', ltrim($fooOrBar, $foo));
+		assertType('\'\'|\'bar\'', rtrim($fooOrBar, $foo));
+
+		assertType('string', trim($constantOrFooClass, '\\'));
+		assertType('string', ltrim($constantOrFooClass, '\\'));
+		assertType('string', rtrim($constantOrFooClass, '\\'));
+		assertType('string', trim($constantOrFooClass, '\\'));
+		assertType('string', ltrim($constantOrFooClass, '\\'));
+		assertType('string', rtrim($constantOrFooClass, '\\'));
+	}
+
+}