diff --git a/.changes/nextrelease/nullable-types.json b/.changes/nextrelease/nullable-types.json
new file mode 100644
index 0000000000..310cb10956
--- /dev/null
+++ b/.changes/nextrelease/nullable-types.json
@@ -0,0 +1,7 @@
+[
+  {
+    "type": "enhancement",
+    "category": "",
+    "description": "Adds nullable operator to implicit nullable type hints."
+  }
+]
diff --git a/composer.json b/composer.json
index 96a57fa838..66f740a342 100644
--- a/composer.json
+++ b/composer.json
@@ -72,4 +72,3 @@
         }
     }
 }
-
diff --git a/features/bootstrap/Aws/Test/Integ/SmokeContext.php b/features/bootstrap/Aws/Test/Integ/SmokeContext.php
index 2d03730f8b..c8f190bea5 100644
--- a/features/bootstrap/Aws/Test/Integ/SmokeContext.php
+++ b/features/bootstrap/Aws/Test/Integ/SmokeContext.php
@@ -393,7 +393,7 @@ public function theResponseShouldContainA($key)
      * @param string $errorCode
      * @param PyStringNode $string
      */
-    public function theErrorCodeShouldBe($errorCode, PyStringNode $string = null)
+    public function theErrorCodeShouldBe($errorCode, ?PyStringNode $string = null)
     {
         $this->iExpectTheResponseErrorCodeToBe($errorCode);
 
diff --git a/features/bootstrap/Aws/Test/UsesServiceTrait.php b/features/bootstrap/Aws/Test/UsesServiceTrait.php
index 41870bf848..e55837538c 100644
--- a/features/bootstrap/Aws/Test/UsesServiceTrait.php
+++ b/features/bootstrap/Aws/Test/UsesServiceTrait.php
@@ -67,8 +67,8 @@ private function getTestClient($service, array $args = [])
     private function addMockResults(
         AwsClientInterface $client,
         array $results,
-        callable $onFulfilled = null,
-        callable $onRejected = null
+        ?callable $onFulfilled = null,
+        ?callable $onRejected = null
     ) {
         foreach ($results as &$res) {
             if (is_array($res)) {
diff --git a/src/Api/ApiProvider.php b/src/Api/ApiProvider.php
index b6a3a559d8..818ff5daf1 100644
--- a/src/Api/ApiProvider.php
+++ b/src/Api/ApiProvider.php
@@ -205,7 +205,7 @@ public function __invoke($type, $service, $version)
      * @param string $modelsDir Directory containing service models.
      * @param array  $manifest  The API version manifest data.
      */
-    private function __construct($modelsDir, array $manifest = null)
+    private function __construct($modelsDir, ?array $manifest = null)
     {
         $this->manifest = $manifest;
         $this->modelsDir = rtrim($modelsDir, '/');
diff --git a/src/Api/ErrorParser/AbstractErrorParser.php b/src/Api/ErrorParser/AbstractErrorParser.php
index efce3d466a..3f5e5b5e95 100644
--- a/src/Api/ErrorParser/AbstractErrorParser.php
+++ b/src/Api/ErrorParser/AbstractErrorParser.php
@@ -21,7 +21,7 @@ abstract class AbstractErrorParser
     /**
      * @param Service $api
      */
-    public function __construct(Service $api = null)
+    public function __construct(?Service $api = null)
     {
         $this->api = $api;
     }
@@ -47,7 +47,7 @@ protected function extractPayload(
     protected function populateShape(
         array &$data,
         ResponseInterface $response,
-        CommandInterface $command = null
+        ?CommandInterface $command = null
     ) {
         $data['body'] = [];
 
diff --git a/src/Api/ErrorParser/JsonRpcErrorParser.php b/src/Api/ErrorParser/JsonRpcErrorParser.php
index 8ac530e945..48e77b4a1d 100644
--- a/src/Api/ErrorParser/JsonRpcErrorParser.php
+++ b/src/Api/ErrorParser/JsonRpcErrorParser.php
@@ -15,7 +15,7 @@ class JsonRpcErrorParser extends AbstractErrorParser
 
     private $parser;
 
-    public function __construct(Service $api = null, JsonParser $parser = null)
+    public function __construct(?Service $api = null, ?JsonParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new JsonParser();
@@ -23,7 +23,7 @@ public function __construct(Service $api = null, JsonParser $parser = null)
 
     public function __invoke(
         ResponseInterface $response,
-        CommandInterface $command = null
+        ?CommandInterface $command = null
     ) {
         $data = $this->genericHandler($response);
 
diff --git a/src/Api/ErrorParser/RestJsonErrorParser.php b/src/Api/ErrorParser/RestJsonErrorParser.php
index 2f7ba818e1..e060d1045e 100644
--- a/src/Api/ErrorParser/RestJsonErrorParser.php
+++ b/src/Api/ErrorParser/RestJsonErrorParser.php
@@ -16,7 +16,7 @@ class RestJsonErrorParser extends AbstractErrorParser
 
     private $parser;
 
-    public function __construct(Service $api = null, JsonParser $parser = null)
+    public function __construct(?Service $api = null, ?JsonParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new JsonParser();
@@ -24,7 +24,7 @@ public function __construct(Service $api = null, JsonParser $parser = null)
 
     public function __invoke(
         ResponseInterface $response,
-        CommandInterface $command = null
+        ?CommandInterface $command = null
     ) {
         $data = $this->genericHandler($response);
 
diff --git a/src/Api/ErrorParser/XmlErrorParser.php b/src/Api/ErrorParser/XmlErrorParser.php
index 41f61a4d30..86f5d0be54 100644
--- a/src/Api/ErrorParser/XmlErrorParser.php
+++ b/src/Api/ErrorParser/XmlErrorParser.php
@@ -17,7 +17,7 @@ class XmlErrorParser extends AbstractErrorParser
 
     protected $parser;
 
-    public function __construct(Service $api = null, XmlParser $parser = null)
+    public function __construct(?Service $api = null, ?XmlParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new XmlParser();
@@ -25,7 +25,7 @@ public function __construct(Service $api = null, XmlParser $parser = null)
 
     public function __invoke(
         ResponseInterface $response,
-        CommandInterface $command = null
+        ?CommandInterface $command = null
     ) {
         $code = (string) $response->getStatusCode();
 
diff --git a/src/Api/Parser/JsonRpcParser.php b/src/Api/Parser/JsonRpcParser.php
index a33da119b8..cd6549c7b2 100644
--- a/src/Api/Parser/JsonRpcParser.php
+++ b/src/Api/Parser/JsonRpcParser.php
@@ -20,7 +20,7 @@ class JsonRpcParser extends AbstractParser
      * @param Service    $api    Service description
      * @param JsonParser $parser JSON body builder
      */
-    public function __construct(Service $api, JsonParser $parser = null)
+    public function __construct(Service $api, ?JsonParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new JsonParser();
diff --git a/src/Api/Parser/QueryParser.php b/src/Api/Parser/QueryParser.php
index 50e4e3a59d..7762ac59d5 100644
--- a/src/Api/Parser/QueryParser.php
+++ b/src/Api/Parser/QueryParser.php
@@ -27,7 +27,7 @@ class QueryParser extends AbstractParser
      */
     public function __construct(
         Service $api,
-        XmlParser $xmlParser = null,
+        ?XmlParser $xmlParser = null,
         $honorResultWrapper = true
     ) {
         parent::__construct($api);
diff --git a/src/Api/Parser/RestJsonParser.php b/src/Api/Parser/RestJsonParser.php
index 76d8098901..bb09f4018b 100644
--- a/src/Api/Parser/RestJsonParser.php
+++ b/src/Api/Parser/RestJsonParser.php
@@ -17,7 +17,7 @@ class RestJsonParser extends AbstractRestParser
      * @param Service    $api    Service description
      * @param JsonParser $parser JSON body builder
      */
-    public function __construct(Service $api, JsonParser $parser = null)
+    public function __construct(Service $api, ?JsonParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new JsonParser();
diff --git a/src/Api/Parser/RestXmlParser.php b/src/Api/Parser/RestXmlParser.php
index d04429f677..057c00ce3a 100644
--- a/src/Api/Parser/RestXmlParser.php
+++ b/src/Api/Parser/RestXmlParser.php
@@ -17,7 +17,7 @@ class RestXmlParser extends AbstractRestParser
      * @param Service   $api    Service description
      * @param XmlParser $parser XML body parser
      */
-    public function __construct(Service $api, XmlParser $parser = null)
+    public function __construct(Service $api, ?XmlParser $parser = null)
     {
         parent::__construct($api);
         $this->parser = $parser ?: new XmlParser();
diff --git a/src/Api/Serializer/JsonRpcSerializer.php b/src/Api/Serializer/JsonRpcSerializer.php
index 643b5c0ff8..61845b08f8 100644
--- a/src/Api/Serializer/JsonRpcSerializer.php
+++ b/src/Api/Serializer/JsonRpcSerializer.php
@@ -36,7 +36,7 @@ class JsonRpcSerializer
     public function __construct(
         Service $api,
         $endpoint,
-        JsonBody $jsonFormatter = null
+        ?JsonBody $jsonFormatter = null
     ) {
         $this->endpoint = $endpoint;
         $this->api = $api;
diff --git a/src/Api/Serializer/QuerySerializer.php b/src/Api/Serializer/QuerySerializer.php
index 7d60661af9..1a55b03e31 100644
--- a/src/Api/Serializer/QuerySerializer.php
+++ b/src/Api/Serializer/QuerySerializer.php
@@ -24,7 +24,7 @@ class QuerySerializer
     public function __construct(
         Service $api,
         $endpoint,
-        callable $paramBuilder = null
+        ?callable $paramBuilder = null
     ) {
         $this->api = $api;
         $this->endpoint = $endpoint;
diff --git a/src/Api/Serializer/RestJsonSerializer.php b/src/Api/Serializer/RestJsonSerializer.php
index 8a2aa993b1..2e281211f2 100644
--- a/src/Api/Serializer/RestJsonSerializer.php
+++ b/src/Api/Serializer/RestJsonSerializer.php
@@ -24,7 +24,7 @@ class RestJsonSerializer extends RestSerializer
     public function __construct(
         Service $api,
         $endpoint,
-        JsonBody $jsonFormatter = null
+        ?JsonBody $jsonFormatter = null
     ) {
         parent::__construct($api, $endpoint);
         $this->contentType = JsonBody::getContentType($api);
diff --git a/src/Api/Serializer/RestXmlSerializer.php b/src/Api/Serializer/RestXmlSerializer.php
index 200b89aaa8..5e7bc6460f 100644
--- a/src/Api/Serializer/RestXmlSerializer.php
+++ b/src/Api/Serializer/RestXmlSerializer.php
@@ -20,7 +20,7 @@ class RestXmlSerializer extends RestSerializer
     public function __construct(
         Service $api,
         $endpoint,
-        XmlBody $xmlBody = null
+        ?XmlBody $xmlBody = null
     ) {
         parent::__construct($api, $endpoint);
         $this->xmlBody = $xmlBody ?: new XmlBody($api);
diff --git a/src/Api/Service.php b/src/Api/Service.php
index 52cc731776..5d7675befc 100644
--- a/src/Api/Service.php
+++ b/src/Api/Service.php
@@ -114,7 +114,7 @@ public static function createSerializer(Service $api, $endpoint)
      * @return callable
      * @throws \UnexpectedValueException
      */
-    public static function createErrorParser($protocol, Service $api = null)
+    public static function createErrorParser($protocol, ?Service $api = null)
     {
         static $mapping = [
             'json'      => ErrorParser\JsonRpcErrorParser::class,
diff --git a/src/Api/Validator.php b/src/Api/Validator.php
index a09aa2c6b5..886092645b 100644
--- a/src/Api/Validator.php
+++ b/src/Api/Validator.php
@@ -25,7 +25,7 @@ class Validator
      *                           "max", and "pattern". If a key is not
      *                           provided, the constraint will assume false.
      */
-    public function __construct(array $constraints = null)
+    public function __construct(?array $constraints = null)
     {
         static $assumedFalseValues = [
             'required' => false,
diff --git a/src/Auth/AuthSchemeResolver.php b/src/Auth/AuthSchemeResolver.php
index b477468094..0dbf309858 100644
--- a/src/Auth/AuthSchemeResolver.php
+++ b/src/Auth/AuthSchemeResolver.php
@@ -37,7 +37,7 @@ class AuthSchemeResolver implements AuthSchemeResolverInterface
 
     public function __construct(
         callable $credentialProvider,
-        callable $tokenProvider = null,
+        ?callable $tokenProvider = null,
         array $authSchemeMap = []
     ){
         $this->credentialProvider = $credentialProvider;
diff --git a/src/CloudSearchDomain/CloudSearchDomainClient.php b/src/CloudSearchDomain/CloudSearchDomainClient.php
index a5971b7830..8b01a2a13c 100644
--- a/src/CloudSearchDomain/CloudSearchDomainClient.php
+++ b/src/CloudSearchDomain/CloudSearchDomainClient.php
@@ -51,7 +51,7 @@ private function searchByPost()
         return static function (callable $handler) {
             return function (
                 CommandInterface $c,
-                RequestInterface $r = null
+                ?RequestInterface $r = null
             ) use ($handler) {
                 if ($c->getName() !== 'Search') {
                     return $handler($c, $r);
diff --git a/src/Command.php b/src/Command.php
index b15af4df4e..4c0a9c54ea 100644
--- a/src/Command.php
+++ b/src/Command.php
@@ -26,7 +26,7 @@ class Command implements CommandInterface
      * @param array       $args           Arguments to pass to the command
      * @param HandlerList $list           Handler list
      */
-    public function __construct($name, array $args = [], HandlerList $list = null)
+    public function __construct($name, array $args = [], ?HandlerList $list = null)
     {
         $this->name = $name;
         $this->data = $args;
diff --git a/src/EndpointV2/EndpointV2Middleware.php b/src/EndpointV2/EndpointV2Middleware.php
index b1628bcb47..fc8861e109 100644
--- a/src/EndpointV2/EndpointV2Middleware.php
+++ b/src/EndpointV2/EndpointV2Middleware.php
@@ -77,7 +77,7 @@ public function __construct(
         EndpointProviderV2 $endpointProvider,
         Service $api,
         array $args,
-        callable $credentialProvider = null
+        ?callable $credentialProvider = null
     )
     {
         $this->nextHandler = $nextHandler;
diff --git a/src/Exception/AwsException.php b/src/Exception/AwsException.php
index 2873d29a35..05b7b955f0 100644
--- a/src/Exception/AwsException.php
+++ b/src/Exception/AwsException.php
@@ -48,7 +48,7 @@ public function __construct(
         $message,
         CommandInterface $command,
         array $context = [],
-        \Exception $previous = null
+        ?\Exception $previous = null
     ) {
         $this->data = isset($context['body']) ? $context['body'] : [];
         $this->command = $command;
diff --git a/src/Exception/CouldNotCreateChecksumException.php b/src/Exception/CouldNotCreateChecksumException.php
index 5c5f80efdd..4697bd6281 100644
--- a/src/Exception/CouldNotCreateChecksumException.php
+++ b/src/Exception/CouldNotCreateChecksumException.php
@@ -9,7 +9,7 @@ class CouldNotCreateChecksumException extends \RuntimeException implements
 {
     use HasMonitoringEventsTrait;
 
-    public function __construct($algorithm, \Exception $previous = null)
+    public function __construct($algorithm, ?\Exception $previous = null)
     {
         $prefix = $algorithm === 'md5' ? "An" : "A";
         parent::__construct("{$prefix} {$algorithm} checksum could not be "
diff --git a/src/Glacier/GlacierClient.php b/src/Glacier/GlacierClient.php
index a9a335c3e1..a800a11c3d 100644
--- a/src/Glacier/GlacierClient.php
+++ b/src/Glacier/GlacierClient.php
@@ -124,7 +124,7 @@ private function getChecksumsMiddleware()
         return function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 // Accept "ContentSHA256" with a lowercase "c" to match other Glacier params.
                 if (!$command['ContentSHA256'] && $command['contentSHA256']) {
@@ -195,7 +195,7 @@ private function getApiVersionMiddleware()
         return function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 return $handler($command, $request->withHeader(
                     'x-amz-glacier-version',
diff --git a/src/Handler/GuzzleV5/GuzzleHandler.php b/src/Handler/GuzzleV5/GuzzleHandler.php
index cbe78eb74d..d97f22b2aa 100644
--- a/src/Handler/GuzzleV5/GuzzleHandler.php
+++ b/src/Handler/GuzzleV5/GuzzleHandler.php
@@ -44,7 +44,7 @@ class GuzzleHandler
     /**
      * @param ClientInterface $client
      */
-    public function __construct(ClientInterface $client = null)
+    public function __construct(?ClientInterface $client = null)
     {
         $this->client = $client ?: new Client();
     }
diff --git a/src/Handler/GuzzleV6/GuzzleHandler.php b/src/Handler/GuzzleV6/GuzzleHandler.php
index 5cbaed070e..c9116d7489 100644
--- a/src/Handler/GuzzleV6/GuzzleHandler.php
+++ b/src/Handler/GuzzleV6/GuzzleHandler.php
@@ -21,7 +21,7 @@ class GuzzleHandler
     /**
      * @param ClientInterface $client
      */
-    public function __construct(ClientInterface $client = null)
+    public function __construct(?ClientInterface $client = null)
     {
         $this->client = $client ?: new Client();
     }
diff --git a/src/HandlerList.php b/src/HandlerList.php
index fccfdb4723..c5a706e10b 100644
--- a/src/HandlerList.php
+++ b/src/HandlerList.php
@@ -61,7 +61,7 @@ class HandlerList implements \Countable
     /**
      * @param callable $handler HTTP handler.
      */
-    public function __construct(callable $handler = null)
+    public function __construct(?callable $handler = null)
     {
         $this->handler = $handler;
     }
@@ -277,7 +277,7 @@ public function remove($nameOrInstance)
      *
      * @param callable|null $fn Pass null to remove any previously set function
      */
-    public function interpose(callable $fn = null)
+    public function interpose(?callable $fn = null)
     {
         $this->sorted = null;
         $this->interposeFn = $fn;
diff --git a/src/HashingStream.php b/src/HashingStream.php
index 6622178e91..c2fd2519eb 100644
--- a/src/HashingStream.php
+++ b/src/HashingStream.php
@@ -29,7 +29,7 @@ class HashingStream implements StreamInterface
     public function __construct(
         StreamInterface $stream,
         HashInterface $hash,
-        callable $onComplete = null
+        ?callable $onComplete = null
     ) {
         $this->stream = $stream;
         $this->hash = $hash;
diff --git a/src/IdempotencyTokenMiddleware.php b/src/IdempotencyTokenMiddleware.php
index dd0de426b8..a325cceec7 100644
--- a/src/IdempotencyTokenMiddleware.php
+++ b/src/IdempotencyTokenMiddleware.php
@@ -37,7 +37,7 @@ class IdempotencyTokenMiddleware
      */
     public static function wrap(
         Service $service,
-        callable $bytesGenerator = null
+        ?callable $bytesGenerator = null
     ) {
         return function (callable $handler) use ($service, $bytesGenerator) {
             return new self($handler, $service, $bytesGenerator);
@@ -47,7 +47,7 @@ public static function wrap(
     public function __construct(
         callable $nextHandler,
         Service $service,
-        callable $bytesGenerator = null
+        ?callable $bytesGenerator = null
     ) {
         $this->bytesGenerator = $bytesGenerator
             ?: $this->findCompatibleRandomSource();
@@ -57,7 +57,7 @@ public function __construct(
 
     public function __invoke(
         CommandInterface $command,
-        RequestInterface $request = null
+        ?RequestInterface $request = null
     ) {
         $handler = $this->nextHandler;
         if ($this->bytesGenerator) {
diff --git a/src/MachineLearning/MachineLearningClient.php b/src/MachineLearning/MachineLearningClient.php
index 72e5ae625d..99378b59fe 100644
--- a/src/MachineLearning/MachineLearningClient.php
+++ b/src/MachineLearning/MachineLearningClient.php
@@ -85,7 +85,7 @@ private function predictEndpoint()
         return static function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 if ($command->getName() === 'Predict') {
                     $request = $request->withUri(new Uri($command['PredictEndpoint']));
diff --git a/src/Middleware.php b/src/Middleware.php
index cb627efc04..6a8c37a1a0 100644
--- a/src/Middleware.php
+++ b/src/Middleware.php
@@ -38,7 +38,7 @@ public static function sourceFile(
         ) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null)
+                ?RequestInterface $request = null)
             use (
                 $handler,
                 $api,
@@ -67,13 +67,13 @@ public static function sourceFile(
      *
      * @return callable
      */
-    public static function validation(Service $api, Validator $validator = null)
+    public static function validation(Service $api, ?Validator $validator = null)
     {
         $validator = $validator ?: new Validator();
         return function (callable $handler) use ($api, $validator) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($api, $validator, $handler) {
                 if ($api->isModifiedModel()) {
                     $api = new Service(
@@ -178,7 +178,7 @@ public static function tap(callable $fn)
         return function (callable $handler) use ($fn) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $fn) {
                 $fn($command, $request);
                 return $handler($command, $request);
@@ -204,8 +204,8 @@ public static function tap(callable $fn)
      * @return callable
      */
     public static function retry(
-        callable $decider = null,
-        callable $delay = null,
+        ?callable $decider = null,
+        ?callable $delay = null,
         $stats = false
     ) {
         $decider = $decider ?: RetryMiddleware::createDefaultDecider();
@@ -253,7 +253,7 @@ public static function contentType(array $operations)
         return function (callable $handler) use ($operations) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $operations) {
                 if (!$request->hasHeader('Content-Type')
                     && in_array($command->getName(), $operations, true)
@@ -322,7 +322,7 @@ public static function history(History $history)
         return function (callable $handler) use ($history) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $history) {
                 $ticket = $history->start($command, $request);
                 return $handler($command, $request)
@@ -354,7 +354,7 @@ public static function mapRequest(callable $f)
         return function (callable $handler) use ($f) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $f) {
                 return $handler($command, $f($request));
             };
@@ -375,7 +375,7 @@ public static function mapCommand(callable $f)
         return function (callable $handler) use ($f) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $f) {
                 return $handler($f($command), $request);
             };
@@ -395,7 +395,7 @@ public static function mapResult(callable $f)
         return function (callable $handler) use ($f) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $f) {
                 return $handler($command, $request)->then($f);
             };
@@ -407,7 +407,7 @@ public static function timer()
         return function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 $start = microtime(true);
                 return $handler($command, $request)
diff --git a/src/MockHandler.php b/src/MockHandler.php
index 22b1421758..a657573796 100644
--- a/src/MockHandler.php
+++ b/src/MockHandler.php
@@ -30,8 +30,8 @@ class MockHandler implements \Countable
      */
     public function __construct(
         array $resultOrQueue = [],
-        callable $onFulfilled = null,
-        callable $onRejected = null
+        ?callable $onFulfilled = null,
+        ?callable $onRejected = null
     ) {
         $this->queue = [];
         $this->onFulfilled = $onFulfilled;
diff --git a/src/Multipart/AbstractUploadManager.php b/src/Multipart/AbstractUploadManager.php
index e663245e0d..d728420fb0 100644
--- a/src/Multipart/AbstractUploadManager.php
+++ b/src/Multipart/AbstractUploadManager.php
@@ -287,7 +287,7 @@ protected function getResultHandler(&$errors = [])
         return function (callable $handler) use (&$errors) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, &$errors) {
                 return $handler($command, $request)->then(
                     function (ResultInterface $result) use ($command) {
diff --git a/src/PresignUrlMiddleware.php b/src/PresignUrlMiddleware.php
index f1f41e1acc..6fb3c92fa4 100644
--- a/src/PresignUrlMiddleware.php
+++ b/src/PresignUrlMiddleware.php
@@ -56,7 +56,7 @@ public static function wrap(
         };
     }
 
-    public function __invoke(CommandInterface $cmd, RequestInterface $request = null)
+    public function __invoke(CommandInterface $cmd, ?RequestInterface $request = null)
     {
         if (in_array($cmd->getName(), $this->commandPool)
             && (!isset($cmd['__skip' . $cmd->getName()]))
diff --git a/src/ResultPaginator.php b/src/ResultPaginator.php
index 2b0c7c9af0..69c2536bee 100644
--- a/src/ResultPaginator.php
+++ b/src/ResultPaginator.php
@@ -162,7 +162,7 @@ public function rewind()
         $this->result = null;
     }
 
-    private function createNextCommand(array $args, array $nextToken = null)
+    private function createNextCommand(array $args, ?array $nextToken = null)
     {
         return $this->client->getCommand($this->operation, array_merge($args, ($nextToken ?: [])));
     }
diff --git a/src/RetryMiddleware.php b/src/RetryMiddleware.php
index 4fa81e9871..bb550df976 100644
--- a/src/RetryMiddleware.php
+++ b/src/RetryMiddleware.php
@@ -87,7 +87,7 @@ public static function createDefaultDecider(
             $retries,
             CommandInterface $command,
             RequestInterface $request,
-            ResultInterface $result = null,
+            ?ResultInterface $result = null,
             $error = null
         ) use ($maxRetries, $retryCurlErrors, $extraConfig) {
             // Allow command-level options to override this value
@@ -216,7 +216,7 @@ public static function exponentialDelay($retries)
      */
     public function __invoke(
         CommandInterface $command,
-        RequestInterface $request = null
+        ?RequestInterface $request = null
     ) {
         $retries = 0;
         $requestStats = [];
diff --git a/src/Route53/Route53Client.php b/src/Route53/Route53Client.php
index 60165b276c..58b6ad19db 100644
--- a/src/Route53/Route53Client.php
+++ b/src/Route53/Route53Client.php
@@ -160,7 +160,7 @@ public function __construct(array $args)
     private function cleanIdFn()
     {
         return function (callable $handler) {
-            return function (CommandInterface $c, RequestInterface $r = null) use ($handler) {
+            return function (CommandInterface $c, ?RequestInterface $r = null) use ($handler) {
                 foreach (['Id', 'HostedZoneId', 'DelegationSetId'] as $clean) {
                     if ($c->hasParam($clean)) {
                         $c[$clean] = $this->cleanId($c[$clean]);
diff --git a/src/S3/ExpiresParsingMiddleware.php b/src/S3/ExpiresParsingMiddleware.php
index 5ceccd1eaa..5bdb34a70d 100644
--- a/src/S3/ExpiresParsingMiddleware.php
+++ b/src/S3/ExpiresParsingMiddleware.php
@@ -36,7 +36,7 @@ public function __construct(callable $nextHandler)
         $this->nextHandler = $nextHandler;
     }
 
-    public function __invoke(CommandInterface $command, RequestInterface $request = null)
+    public function __invoke(CommandInterface $command, ?RequestInterface $request = null)
     {
         $next = $this->nextHandler;
         return $next($command, $request)->then(
diff --git a/src/S3/Parser/ValidateResponseChecksumResultMutator.php b/src/S3/Parser/ValidateResponseChecksumResultMutator.php
index d1abd995b1..3a31c4e813 100644
--- a/src/S3/Parser/ValidateResponseChecksumResultMutator.php
+++ b/src/S3/Parser/ValidateResponseChecksumResultMutator.php
@@ -37,8 +37,8 @@ public function __construct(Service $api)
      */
     public function __invoke(
         ResultInterface $result,
-        CommandInterface $command = null,
-        ResponseInterface $response = null
+        ?CommandInterface $command = null,
+        ?ResponseInterface $response = null
     ): ResultInterface
     {
         $operation = $this->api->getOperation($command->getName());
diff --git a/src/S3/PermanentRedirectMiddleware.php b/src/S3/PermanentRedirectMiddleware.php
index eb4b8e337f..36a0e683ea 100644
--- a/src/S3/PermanentRedirectMiddleware.php
+++ b/src/S3/PermanentRedirectMiddleware.php
@@ -37,7 +37,7 @@ public function __construct(callable $nextHandler)
         $this->nextHandler = $nextHandler;
     }
 
-    public function __invoke(CommandInterface $command, RequestInterface $request = null)
+    public function __invoke(CommandInterface $command, ?RequestInterface $request = null)
     {
         $next = $this->nextHandler;
         return $next($command, $request)->then(
diff --git a/src/S3/PutObjectUrlMiddleware.php b/src/S3/PutObjectUrlMiddleware.php
index 4ad4ebbf44..9b80406eca 100644
--- a/src/S3/PutObjectUrlMiddleware.php
+++ b/src/S3/PutObjectUrlMiddleware.php
@@ -35,7 +35,7 @@ public function __construct(callable $nextHandler)
         $this->nextHandler = $nextHandler;
     }
 
-    public function __invoke(CommandInterface $command, RequestInterface $request = null)
+    public function __invoke(CommandInterface $command, ?RequestInterface $request = null)
     {
         $next = $this->nextHandler;
         return $next($command, $request)->then(
diff --git a/src/S3/S3Client.php b/src/S3/S3Client.php
index bcd0bbcc6f..c9a37c3f5c 100644
--- a/src/S3/S3Client.php
+++ b/src/S3/S3Client.php
@@ -620,7 +620,7 @@ private function getHeadObjectMiddleware()
         return static function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 if ($command->getName() === 'HeadObject'
                     && !isset($command['@http']['decode_content'])
@@ -721,7 +721,7 @@ private function getDisableExpressSessionAuthMiddleware()
         return function (callable $handler) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler) {
                 if (!empty($command['@context']['signature_version'])
                     && $command['@context']['signature_version'] === 'v4-s3express'
diff --git a/src/S3/SSECMiddleware.php b/src/S3/SSECMiddleware.php
index 9435a209dd..628ddef159 100644
--- a/src/S3/SSECMiddleware.php
+++ b/src/S3/SSECMiddleware.php
@@ -35,7 +35,7 @@ public function __construct($endpointScheme, callable $nextHandler)
 
     public function __invoke(
         CommandInterface $command,
-        RequestInterface $request = null
+        ?RequestInterface $request = null
     ) {
         // Allows only HTTPS connections when using SSE-C
         if (($command['SSECustomerKey'] || $command['CopySourceSSECustomerKey'])
diff --git a/src/S3/StreamWrapper.php b/src/S3/StreamWrapper.php
index a70e5cd52d..5ceac36e80 100644
--- a/src/S3/StreamWrapper.php
+++ b/src/S3/StreamWrapper.php
@@ -110,7 +110,7 @@ class StreamWrapper
     public static function register(
         S3ClientInterface $client,
         $protocol = 's3',
-        CacheInterface $cache = null,
+        ?CacheInterface $cache = null,
         $v2Existence = false
     ) {
         self::$useV2Existence = $v2Existence;
diff --git a/src/Script/Composer/Composer.php b/src/Script/Composer/Composer.php
index d2b18cb359..765d0c24c2 100644
--- a/src/Script/Composer/Composer.php
+++ b/src/Script/Composer/Composer.php
@@ -8,17 +8,17 @@
 class Composer
 {
 
-    public static function removeUnusedServicesInDev(Event $event, Filesystem $filesystem = null)
+    public static function removeUnusedServicesInDev(Event $event, ?Filesystem $filesystem = null)
     {
         self::removeUnusedServicesWithConfig($event, $filesystem, true);
     }
 
-    public static function removeUnusedServices(Event $event, Filesystem $filesystem = null)
+    public static function removeUnusedServices(Event $event, ?Filesystem $filesystem = null)
     {
         self::removeUnusedServicesWithConfig($event, $filesystem, false);
     }
 
-    private static function removeUnusedServicesWithConfig(Event $event, Filesystem $filesystem = null, $isDev = false)
+    private static function removeUnusedServicesWithConfig(Event $event, ?Filesystem $filesystem = null, $isDev = false)
     {
         if ($isDev && !$event->isDevMode()){
             return;
diff --git a/src/Signature/S3SignatureV4.php b/src/Signature/S3SignatureV4.php
index b47c0d5dbe..52a9f4e7dc 100644
--- a/src/Signature/S3SignatureV4.php
+++ b/src/Signature/S3SignatureV4.php
@@ -58,7 +58,7 @@ protected function signWithV4a(
         CredentialsInterface $credentials,
         RequestInterface $request,
         $signingService,
-        SigningConfigAWS $signingConfig = null
+        ?SigningConfigAWS $signingConfig = null
     ){
         $this->verifyCRTLoaded();
         $credentials_provider = $this->createCRTStaticCredentialsProvider($credentials);
diff --git a/src/Signature/SignatureV4.php b/src/Signature/SignatureV4.php
index cf94befa77..7b9fcef501 100644
--- a/src/Signature/SignatureV4.php
+++ b/src/Signature/SignatureV4.php
@@ -508,7 +508,7 @@ protected function signWithV4a(
         CredentialsInterface $credentials,
         RequestInterface $request,
         $signingService,
-        SigningConfigAWS $signingConfig = null
+        ?SigningConfigAWS $signingConfig = null
     ){
         $this->verifyCRTLoaded();
         $signingConfig = $signingConfig ?? new SigningConfigAWS([
diff --git a/src/Sqs/SqsClient.php b/src/Sqs/SqsClient.php
index b54e12a79c..075fc9b6a3 100644
--- a/src/Sqs/SqsClient.php
+++ b/src/Sqs/SqsClient.php
@@ -169,7 +169,7 @@ private function validateMd5()
         return static function (callable $handler) {
             return function (
                 CommandInterface $c,
-                RequestInterface $r = null
+                ?RequestInterface $r = null
             ) use ($handler) {
                 if ($c->getName() !== 'ReceiveMessage') {
                     return $handler($c, $r);
diff --git a/src/Token/SsoTokenProvider.php b/src/Token/SsoTokenProvider.php
index 777fe25dcc..13345a7cde 100644
--- a/src/Token/SsoTokenProvider.php
+++ b/src/Token/SsoTokenProvider.php
@@ -37,7 +37,7 @@ class SsoTokenProvider implements RefreshableTokenProviderInterface
     public function __construct(
         $profileName,
         $configFilePath = null,
-        SSOOIDCClient $ssoOidcClient = null
+        ?SSOOIDCClient $ssoOidcClient = null
     ) {
         $this->profileName = $this->resolveProfileName($profileName);
         $this->configFilePath =  $this->resolveConfigFile($configFilePath);
diff --git a/src/TraceMiddleware.php b/src/TraceMiddleware.php
index 46f1d5198f..032043b8e3 100644
--- a/src/TraceMiddleware.php
+++ b/src/TraceMiddleware.php
@@ -61,7 +61,7 @@ class TraceMiddleware
      *   headers contained in this array will be replaced with the if
      *   "scrub_auth" is set to true.
      */
-    public function __construct(array $config = [], Service $service = null)
+    public function __construct(array $config = [], ?Service $service = null)
     {
         $this->config = $config + [
             'logfn'        => function ($value) { echo $value; },
@@ -179,7 +179,7 @@ private function requestArray($request = null)
         ]);
     }
 
-    private function responseArray(ResponseInterface $response = null)
+    private function responseArray(?ResponseInterface $response = null)
     {
         return !$response ? [] : [
             'instance'   => spl_object_hash($response),
diff --git a/tests/Credentials/EcsCredentialProviderTest.php b/tests/Credentials/EcsCredentialProviderTest.php
index 78cf54a209..68d2e84f85 100644
--- a/tests/Credentials/EcsCredentialProviderTest.php
+++ b/tests/Credentials/EcsCredentialProviderTest.php
@@ -215,7 +215,7 @@ private function getCredentialArray(
         ];
     }
 
-    private function getTestCreds($result, Response $more = null)
+    private function getTestCreds($result, ?Response $more = null)
     {
         $responses = [];
         $responses[] = new Response(200, [], Psr7\Utils::streamFor(json_encode($result)));
@@ -237,7 +237,7 @@ private function getTestCreds($result, Response $more = null)
         return $provider();
     }
 
-    private function resolveCredentials($result, Response $more = null)
+    private function resolveCredentials($result, ?Response $more = null)
     {
         $responses = [];
         $responses[] = new Response(200, [], Psr7\Utils::streamFor(json_encode($result)));
diff --git a/tests/Glacier/MultipartUploaderTest.php b/tests/Glacier/MultipartUploaderTest.php
index eb32d8aad1..023dd21d19 100644
--- a/tests/Glacier/MultipartUploaderTest.php
+++ b/tests/Glacier/MultipartUploaderTest.php
@@ -28,7 +28,7 @@ public static function _tearDownAfterClass()
      */
     public function testGlacierMultipartUploadWorkflow(
         array $uploadOptions = [],
-        StreamInterface $source = null,
+        ?StreamInterface $source = null,
         $error = false
     ) {
         $client = $this->getTestClient('glacier');
diff --git a/tests/Integ/SmokeContext.php b/tests/Integ/SmokeContext.php
index 2d03730f8b..c8f190bea5 100644
--- a/tests/Integ/SmokeContext.php
+++ b/tests/Integ/SmokeContext.php
@@ -393,7 +393,7 @@ public function theResponseShouldContainA($key)
      * @param string $errorCode
      * @param PyStringNode $string
      */
-    public function theErrorCodeShouldBe($errorCode, PyStringNode $string = null)
+    public function theErrorCodeShouldBe($errorCode, ?PyStringNode $string = null)
     {
         $this->iExpectTheResponseErrorCodeToBe($errorCode);
 
diff --git a/tests/S3/Crypto/S3EncryptionClientTest.php b/tests/S3/Crypto/S3EncryptionClientTest.php
index 6eb53f30fa..f0f07d201a 100644
--- a/tests/S3/Crypto/S3EncryptionClientTest.php
+++ b/tests/S3/Crypto/S3EncryptionClientTest.php
@@ -254,7 +254,7 @@ public function testPutObjectWithOperationInstructionFileSuffix()
     public function testPutObjectValidatesCipher(
         $cipher,
         $exception = null,
-        callable $skipCheck = null
+        ?callable $skipCheck = null
     ) {
         if ($skipCheck && $skipCheck()) {
             $this->markTestSkipped(
diff --git a/tests/S3/Crypto/S3EncryptionMultipartUploaderTest.php b/tests/S3/Crypto/S3EncryptionMultipartUploaderTest.php
index 328cf8b46c..72de97710d 100644
--- a/tests/S3/Crypto/S3EncryptionMultipartUploaderTest.php
+++ b/tests/S3/Crypto/S3EncryptionMultipartUploaderTest.php
@@ -251,7 +251,7 @@ public function testPutObjectWithClientInstructionFileSuffix()
     public function testPutObjectValidatesCipher(
         $cipher,
         $exception = null,
-        callable $skipCheck = null
+        ?callable $skipCheck = null
     ) {
         if ($skipCheck && $skipCheck()) {
             $this->markTestSkipped(
diff --git a/tests/S3/MultipartUploaderTest.php b/tests/S3/MultipartUploaderTest.php
index 6abfaa8277..b8a46e55dd 100644
--- a/tests/S3/MultipartUploaderTest.php
+++ b/tests/S3/MultipartUploaderTest.php
@@ -32,7 +32,7 @@ public static function tear_down_after_class()
     public function testS3MultipartUploadWorkflow(
         array $clientOptions = [],
         array $uploadOptions = [],
-        StreamInterface $source = null,
+        ?StreamInterface $source = null,
         $error = false
     ) {
         $client = $this->getTestClient('s3', $clientOptions);
diff --git a/tests/S3/TransferTest.php b/tests/S3/TransferTest.php
index 170d20c4d2..4828888ad9 100644
--- a/tests/S3/TransferTest.php
+++ b/tests/S3/TransferTest.php
@@ -407,7 +407,7 @@ private function mockResult(callable $fn)
         return function (callable $handler) use ($fn) {
             return function (
                 CommandInterface $command,
-                RequestInterface $request = null
+                ?RequestInterface $request = null
             ) use ($handler, $fn) {
                 return Promise\Create::promiseFor($fn($command, $request));
             };
diff --git a/tests/UsesServiceTrait.php b/tests/UsesServiceTrait.php
index 41870bf848..e55837538c 100644
--- a/tests/UsesServiceTrait.php
+++ b/tests/UsesServiceTrait.php
@@ -67,8 +67,8 @@ private function getTestClient($service, array $args = [])
     private function addMockResults(
         AwsClientInterface $client,
         array $results,
-        callable $onFulfilled = null,
-        callable $onRejected = null
+        ?callable $onFulfilled = null,
+        ?callable $onRejected = null
     ) {
         foreach ($results as &$res) {
             if (is_array($res)) {
diff --git a/tests/bootstrap/PHPUnit_Framework_MockObject_Generator_7.4.php b/tests/bootstrap/PHPUnit_Framework_MockObject_Generator_7.4.php
index a326dd06cb..1e40de4932 100644
--- a/tests/bootstrap/PHPUnit_Framework_MockObject_Generator_7.4.php
+++ b/tests/bootstrap/PHPUnit_Framework_MockObject_Generator_7.4.php
@@ -544,7 +544,7 @@ public function getObjectForTrait($traitName, array $arguments = [], $traitClass
      *
      * @return array
      */
-    public function generate($type, array $methods = null, $mockClassName = '', $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false)
+    public function generate($type, ?array $methods = null, $mockClassName = '', $callOriginalClone = true, $callAutoload = true, $cloneArguments = true, $callOriginalMethods = false)
     {
         if (is_array($type)) {
             sort($type);