### Summary

If the argument spec defines a dict variable as required:

- if the variable has no default in defaults/main.yml and is not provided in the playbook, argument spec validation will fail. That's OK.
- if the variable is defined as a string e.g. `''` or `'test-string'`, validation will fail. That's OK.
- if the variable is defines as None or `~`, validation will pass. That's NOT OK.

### Issue Type

Bug Report

### Component Name

argument_spec

### Ansible Version

```console
$ ansible --version
ansible [core 2.15.0.dev0] (devel 51bddd862b) last updated 2023/01/03 22:32:16 (GMT +000)
  config file = /home/nikos/projects/ansible-demo/ansible.cfg
  configured module search path = ['/home/nikos/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/nikos/projects/ansible/lib/ansible
  ansible collection location = /home/nikos/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/nikos/projects/ansible/bin/ansible
  python version = 3.10.8 (main, Nov  1 2022, 14:18:21) [GCC 12.2.0] (/usr/bin/python)
  jinja version = 3.1.2
  libyaml = True
```


### Configuration

```console
# if using a version older than ansible-core 2.12 you should omit the '-t all'
$ ansible-config dump --only-changed -t all
ANSIBLE_NOCOWS(/home/nikos/projects/ansible-demo/ansible.cfg) = True
CACHE_PLUGIN(/home/nikos/projects/ansible-demo/ansible.cfg) = ansible.builtin.json
CACHE_PLUGIN_CONNECTION(/home/nikos/projects/ansible-demo/ansible.cfg) = facts_cache
CONFIG_FILE() = /home/nikos/projects/ansible-demo/ansible.cfg
DEFAULT_EXECUTABLE(/home/nikos/projects/ansible-demo/ansible.cfg) = /bin/bash
DEFAULT_GATHERING(/home/nikos/projects/ansible-demo/ansible.cfg) = implicit
DEFAULT_HOST_LIST(/home/nikos/projects/ansible-demo/ansible.cfg) = ['/home/nikos/projects/ansible-demo/inventory.ini']
DEFAULT_MANAGED_STR(/home/nikos/projects/ansible-demo/ansible.cfg) = \nAnsible managed (do not edit, changes may be overwritten)
EDITOR(env: EDITOR) = nvim

CACHE:
=====

jsonfile:
________
```


### OS / Environment

Controller and target: Arch Linux

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
# role argument specs
---

argument_specs:
  main:
    options:
      dict_var:
        type: dict
        required: true
```

```
# playbook
---

- hosts: all
  roles:
    - myrole
  vars:
    dict_var: ~
```

### Expected Results

I expect argument validation to fail with a message that None type is not dict or could not be converted to dict.

### Actual Results

```console
Validation passes and role execution succeeds.
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct
"""This is for checking for required params when we can not check via
    argspec because we need more information than is simply given in the argspec.
    Raises :class:`TypeError` if any required parameters are missing
    :arg parameters: Dictionary of parameters
    :arg required_parameters: List of parameters to look for in the given parameters.
    :returns: Empty list or raises :class:`TypeError` if the check fails.
    """
    missing_params = []
    if required_parameters is None:
        return missing_params
    for param in required_parameters:
        if not parameters.get(param):
            missing_params.append(param)
    if missing_params:
        msg = "missing required arguments: %s" % ', '.join(missing_params)
        raise TypeError(to_native(msg))
    return missing_params
def check_type_str(value, allow_conversion=True, param=None, prefix=''):