diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2fbcc48cd70fbda3297146feabcda91155621927..f1a2a4ac4f7ed31971eba0f6816ba27127f829a3 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -69,6 +69,14 @@ linter:buster:
     reports:
       codequality: codeclimate.json
 
+linter_typehints:buster:
+  image: registry.git.cccv.de/uffd/docker-images/buster
+  stage: test
+  script:
+  - pip3 install --upgrade pip
+  - pip3 install pytype
+  - pytype --config pytype.cfg
+
 linter:bullseye:
   image: registry.git.cccv.de/uffd/docker-images/bullseye
   stage: test
diff --git a/pytype.cfg b/pytype.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..f7ee3ed9916a1a4aec61a17fba75008b4e3361fa
--- /dev/null
+++ b/pytype.cfg
@@ -0,0 +1,96 @@
+# NOTE: All relative paths are relative to the location of this file.
+
+[pytype]
+
+# Space-separated list of files or directories to exclude.
+exclude =
+    **/*_test.py
+    **/test_*.py
+
+# Space-separated list of files or directories to process.
+inputs =
+    uffd
+
+# Keep going past errors to analyze as many files as possible.
+keep_going = True
+
+# Run N jobs in parallel. When 'auto' is used, this will be equivalent to the
+# number of CPUs on the host system.
+jobs = 4
+
+# All pytype output goes here.
+output = .pytype
+
+# Platform (e.g., "linux", "win32") that the target code runs on.
+platform = linux
+
+# Paths to source code directories, separated by ':'.
+pythonpath =
+    .
+
+# Python version (major.minor) of the target code.
+python_version = 3.9
+
+# Use the enum overlay for more precise enum checking. This flag is temporary
+# and will be removed once this behavior is enabled by default.
+use_enum_overlay = False
+
+# Build dict literals from dict(k=v, ...) calls. This flag is temporary and will
+# be removed once this behavior is enabled by default.
+build_dict_literals_from_kwargs = False
+
+# Enable stricter namedtuple checks, such as unpacking and 'typing.Tuple'
+# compatibility. This flag is temporary and will be removed once this behavior
+# is enabled by default.
+strict_namedtuple_checks = False
+
+# Enable exhaustive checking of function parameter types. This flag is temporary
+# and will be removed once this behavior is enabled by default.
+strict_parameter_checks = False
+
+# Emit errors for comparisons between incompatible primitive types. This flag is
+# temporary and will be removed once this behavior is enabled by default.
+strict_primitive_comparisons = False
+
+# Enable default value checks for overriding methods. This flag is temporary and
+# will be removed once this behavior is enabled by default.
+overriding_default_value_checks = False
+
+# Enable parameter count checks for overriding methods. This flag is temporary
+# and will be removed once this behavior is enabled by default.
+overriding_parameter_count_checks = False
+
+# Enable parameter name checks for overriding methods. This flag is temporary
+# and will be removed once this behavior is enabled by default.
+overriding_parameter_name_checks = False
+
+# Enable parameter type checks for overriding methods. This flag is temporary
+# and will be removed once this behavior is enabled by default.
+overriding_parameter_type_checks = False
+
+# Enable return type checks for overriding methods. This flag is temporary and
+# will be removed once this behavior is enabled by default.
+overriding_return_type_checks = False
+
+# Support pyglib's @cached.property. This flag is temporary and will be removed
+# once this behavior is enabled by default.
+enable_cached_property = False
+
+# Solve unknown types to label with structural types. This flag is temporary and
+# will be removed once this behavior is enabled by default.
+protocols = False
+
+# Only load submodules that are explicitly imported. This flag is temporary and
+# will be removed once this behavior is enabled by default.
+strict_import = False
+
+# Infer precise return types even for invalid function calls. This flag is
+# temporary and will be removed once this behavior is enabled by default.
+precise_return = False
+
+# Comma or space separated list of error names to ignore.
+disable =
+    pyi-error
+
+# Don't report errors.
+report_errors = True
diff --git a/requirements.txt b/requirements.txt
index 4716275e1bd7bf31353727b9ac2b5a93991fc43e..c2ea9e6a62196173d08f41b1df81356401046819 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,6 +2,7 @@
 
 # Testing
 pytest==3.10.1
+pytype==2022.8.17
 atomicwrites==1.1.5
 attrs==18.2.0
 more-itertools==4.2.0