diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f3de909c5a15f18d51c236df497c1ce93c227a7b..61aa2464abaef325181bd7566a76adfecbe6acf7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,9 @@
 stages:
   - test
 
-.test-verify-template: &test-verify-template
+test-verify:
   stage: test
+  image: grifart/php8.0-with-all-modules-and-various-tools
   interruptible: true
 
   before_script:
@@ -10,8 +11,3 @@ stages:
 
   script:
     - composer run verify
-
-
-test.verify.php74:
-  <<: *test-verify-template
-  image: grifart/php7.4-with-gulp-and-all-php-modules
diff --git a/composer.json b/composer.json
index b8daf2405681a4da028fdb5f15edb882a26fe3af..23abd38e50b43dfe47b6625bbbe5d2d918d2f774 100644
--- a/composer.json
+++ b/composer.json
@@ -22,15 +22,15 @@
 
 
     "require": {
-        "php": "^7.4",
+        "php": "^8.0",
         "dibi/dibi": "^4.0.2",
-        "grifart/class-scaffolder": "^0.2.0|^0.3.0",
+        "grifart/class-scaffolder": "^0.4.0",
         "nette/utils": "^3.0.1"
     },
     "require-dev": {
         "nette/tester": "^2.3",
-        "grifart/phpstan-oneline": "^0.2.2",
-        "phpstan/phpstan": "^0.11.17"
+        "grifart/phpstan-oneline": "^0.4.0",
+        "phpstan/phpstan": "^0.12"
 
     },
 
diff --git a/src/Modifications.php b/src/Modifications.php
index 9b3dd6ca3d5e20296014ac5c4faacb8b1ff29a38..6a810af57002764f38fe56d093ab6deef3f309a3 100644
--- a/src/Modifications.php
+++ b/src/Modifications.php
@@ -8,7 +8,10 @@ interface Modifications
 {
 
 
-	/** @internal used by {@see AccountsTable} */
+	/**
+	 * @internal used by {@see AccountsTable}
+	 * @return mixed[]
+	 */
 	public function getModifications(): array;
 
 	/** @return null|PrimaryKey if null it means, that row is new (do INSERT) */
diff --git a/src/PrimaryKey.php b/src/PrimaryKey.php
index 40ac8040000f06986b8c5b029c1b1be997b8c4ef..e90c7da7aa97e90f1be06fe81c2b284b18630acb 100644
--- a/src/PrimaryKey.php
+++ b/src/PrimaryKey.php
@@ -7,7 +7,7 @@ interface PrimaryKey
 {
 
 	/**
-	 * @return array query used in WHERE to narrow down results into one record
+	 * @return array<string, mixed> query used in WHERE to narrow down results into one record
 	 */
 	public function getQuery(): array;
 
diff --git a/src/Row.php b/src/Row.php
index 612691434e73217ad52b3708fa38a4d724d591a6..0db2c7713767f2747e7b6d8025602d2d47ebd5dd 100644
--- a/src/Row.php
+++ b/src/Row.php
@@ -7,7 +7,9 @@ namespace Grifart\Tables;
 interface Row
 {
 
-	/** @return self */
-	public static function reconstitute(array $values);
+	/**
+	 * @param mixed[] $values
+	 */
+	public static function reconstitute(array $values): static;
 
 }
diff --git a/src/Scaffolding/Column.php b/src/Scaffolding/Column.php
index 34086dd1acd8bf963e17056ce9399d3a5060a995..6d1cf634062065b2cbacea69b029df6d87c4d715 100644
--- a/src/Scaffolding/Column.php
+++ b/src/Scaffolding/Column.php
@@ -7,21 +7,12 @@ namespace Grifart\Tables\Scaffolding;
 final class Column
 {
 
-	private string $name;
-
-	private string $type;
-
-	private bool $nullable;
-
-	private bool $hasDefaultValue;
-
-	public function __construct(string $name, string $type, bool $nullable, bool $hasDefaultValue)
-	{
-		$this->name = $name;
-		$this->type = $type;
-		$this->nullable = $nullable;
-		$this->hasDefaultValue = $hasDefaultValue;
-	}
+	public function __construct(
+		private string $name,
+		private string $type,
+		private bool $nullable,
+		private bool $hasDefaultValue,
+	) {}
 
 	public function getName(): string
 	{
diff --git a/src/Scaffolding/PostgresReflector.php b/src/Scaffolding/PostgresReflector.php
index 871dc7d01513f4ad1323c52876ab575c7b4dffc4..a580c8d8e0338cb0d184f946d93963a8bb7912dd 100644
--- a/src/Scaffolding/PostgresReflector.php
+++ b/src/Scaffolding/PostgresReflector.php
@@ -9,13 +9,9 @@ use Dibi\Connection;
 final class PostgresReflector
 {
 
-	/** @var Connection */
-	private $connection;
-
-	public function __construct(Connection $connection)
-	{
-		$this->connection = $connection;
-	}
+	public function __construct(
+		private Connection $connection
+	) {}
 
 	/**
 	 * source: https://stackoverflow.com/a/51897900/631369
diff --git a/src/Scaffolding/PrivateConstructorDecorator.php b/src/Scaffolding/PrivateConstructorDecorator.php
index 0007998e332f424d6d64c4dcb67a7df8c9da0c2c..0889283bc8501ad4bd0a1d90bab1a2caa25711f4 100644
--- a/src/Scaffolding/PrivateConstructorDecorator.php
+++ b/src/Scaffolding/PrivateConstructorDecorator.php
@@ -11,6 +11,6 @@ final class PrivateConstructorDecorator implements ClassDecorator
 
 	public function decorate(ClassType $classType, ClassDefinition $definition): void
 	{
-		$classType->getMethod('__construct')->setVisibility('private');
+		$classType->getMethod('__construct')->setPrivate();
 	}
 }
diff --git a/src/Scaffolding/ReconstituteConstructorDecorator.php b/src/Scaffolding/ReconstituteConstructorDecorator.php
index 046c3cfb121292525875a4d15d43028042c73433..e2739f939588db64df6738f5d1945e615f720693 100644
--- a/src/Scaffolding/ReconstituteConstructorDecorator.php
+++ b/src/Scaffolding/ReconstituteConstructorDecorator.php
@@ -14,7 +14,7 @@ final class ReconstituteConstructorDecorator implements ClassDecorator
 	public function decorate(ClassType $classType, ClassDefinition $definition): void
 	{
 		$reconstitute = $classType->addMethod('reconstitute')
-			->setReturnType('self')
+			->setReturnType('static')
 			->setParameters([(new Code\Parameter('values'))->setTypeHint('array')])
 			->setStatic();
 
@@ -25,6 +25,6 @@ final class ReconstituteConstructorDecorator implements ClassDecorator
 
 		// todo: add array_keys that it contains just keys that are necessary
 
-		$reconstitute->addBody("return new self($questionMarks);", \array_values($literals));
+		$reconstitute->addBody("return new static($questionMarks);", \array_values($literals));
 	}
 }
diff --git a/src/Scaffolding/Scaffolding.php b/src/Scaffolding/Scaffolding.php
index 2edb17cbbf80eaaeaa944334a5e45236026ded2f..d83bd9673324b8c73dbd385af1bd1c0a569758d2 100644
--- a/src/Scaffolding/Scaffolding.php
+++ b/src/Scaffolding/Scaffolding.php
@@ -8,8 +8,8 @@ namespace Grifart\Tables\Scaffolding;
 use Grifart\ClassScaffolder\Decorators\GettersDecorator;
 use Grifart\ClassScaffolder\Decorators\InitializingConstructorDecorator;
 use Grifart\ClassScaffolder\Decorators\PropertiesDecorator;
+use Grifart\ClassScaffolder\Definition\ClassDefinition;
 use Grifart\ClassScaffolder\Definition\ClassDefinitionBuilder;
-use Grifart\ClassScaffolder\Definition\Types\Type;
 use Grifart\Tables\Row;
 use Grifart\Tables\TypeMapper;
 use function Grifart\ClassScaffolder\Definition\Types\nullable;
@@ -23,6 +23,9 @@ final class Scaffolding
 		return "$schema.$table.$column";
 	}
 
+	/**
+	 * @return ClassDefinition[]
+	 */
 	public static function definitionsForPgTable(
 		PostgresReflector $pgReflector,
 		TypeMapper $mapper,
diff --git a/src/Scaffolding/TableDecorator.php b/src/Scaffolding/TableDecorator.php
index 7436f284e35d5a81a98e73d09f5b912e204da483..61b8328974644785381995dcdaaa74f1a28a907a 100644
--- a/src/Scaffolding/TableDecorator.php
+++ b/src/Scaffolding/TableDecorator.php
@@ -18,28 +18,24 @@ use Webmozart\Assert\Assert;
 final class TableDecorator implements ClassDecorator
 {
 
-	/** @var string */
-	private $schema;
+	private string $schema;
 
-	/** @var string */
-	private $tableName;
+	private string $tableName;
 
-	/** @var string */
-	private $primaryKeyClass;
+	private string $primaryKeyClass;
 
-	/** @var string */
-	private $rowClass;
+	private string $rowClass;
 
-	/** @var string */
-	private $modificationClass;
+	private string $modificationClass;
 
 	/** @var Column[] */
-	private $columnInfo;
+	private array $columnInfo;
 
 	/** @var array<string, Type> */
-	private $columnPhpTypes;
+	private array $columnPhpTypes;
 
 	/**
+	 * @param array<string, Column> $columnInfo
 	 * @param array<string, Type> $columnPhpTypes
 	 */
 	public function __construct(string $schema, string $tableName, string $primaryKeyClass, string $rowClass, string $modificationClass, array $columnInfo, array $columnPhpTypes)
@@ -269,7 +265,7 @@ final class TableDecorator implements ClassDecorator
 		$this->implementConfigMethod($classType, $name, new Code\PhpLiteral($namespace->unresolveName($class) . '::class'));
 	}
 
-	private function implementConfigMethod(Code\ClassType $classType, string $name, $value): void
+	private function implementConfigMethod(Code\ClassType $classType, string $name, mixed $value): void
 	{
 		$classType->addMethod($name)
 			->setStatic()
diff --git a/src/TableManager.php b/src/TableManager.php
index e79ed40b7b535bab5c7c69b395403a2e93aa7b32..0a6e04c4debd1a53ec89f100865e9a5ef5d72c84 100644
--- a/src/TableManager.php
+++ b/src/TableManager.php
@@ -15,21 +15,11 @@ use Dibi\Connection;
 final class TableManager
 {
 
-	/** @var Connection */
-	private $connection;
-
-	/** @var TypeMapper */
-	private $phpToDatabaseMapper;
-
-	/** @var TypeMapper */
-	private $databaseToPhpMapper;
-
-	public function __construct(Connection $connection, TypeMapper $phpToDatabaseMapper, TypeMapper $databaseToPhpMapper)
-	{
-		$this->connection = $connection;
-		$this->phpToDatabaseMapper = $phpToDatabaseMapper;
-		$this->databaseToPhpMapper = $databaseToPhpMapper;
-	}
+	public function __construct(
+		private Connection $connection,
+		private TypeMapper $phpToDatabaseMapper,
+		private TypeMapper $databaseToPhpMapper,
+	) {}
 
 
 	public function insert(Table $table, Modifications $changes): void
@@ -55,7 +45,13 @@ final class TableManager
 		return NULL;
 	}
 
-	/** @return Row[] (subclass of row) */
+	/**
+	 * @param array<string, mixed> $conditions Conditions provides low-level access to "where" clause concatenated by %and. 
+	 *                                         More: https://dibiphp.com/en/documentation
+	 *                                         Note! Types and names are currently NOT mapped.
+	 *                                         Please follow https://gitlab.grifart.cz/grifart/tables/-/issues/2 on progress.
+	 * @return Row[] (subclass of row)
+	 */
 	public function findBy(Table $table, array $conditions): array
 	{
 		$result = $this->connection->query(
@@ -114,6 +110,10 @@ final class TableManager
 	}
 
 
+	/**
+	 * @param array<string, mixed> $values
+	 * @return array<string, mixed>
+	 */
 	private static function mapTypes(TypeMapper $mapper, array $values, Table $table): array
 	{
 		// could not use array_map as it does not preserve indexes
diff --git a/src/TypeMapper.php b/src/TypeMapper.php
index 17582a06f2ea0413e09807ee8cd8f158db43fba2..310d60731a2a7eaafa718a3db7149fb1b0393fe4 100644
--- a/src/TypeMapper.php
+++ b/src/TypeMapper.php
@@ -10,12 +10,12 @@ final class TypeMapper
 	/**
 	 * @var (callable(string $typeName, string $location): (string|Type|null))[]
 	 */
-	private $matchers = [];
+	private array $matchers = [];
 
 	/**
 	 * @var (callable(mixed $value, string $typeName): mixed)[]
 	 */
-	private $mappings = [];
+	private array $mappings = [];
 
 
 	/**
@@ -24,12 +24,12 @@ final class TypeMapper
 	 *
 	 * TODO: isn't it too general? Or just map db-type name to php type and back?
 	 */
-	public function addMapping(callable $typeMatcher, callable $mapper) {
+	public function addMapping(callable $typeMatcher, callable $mapper): void {
 		$this->matchers[] = $typeMatcher;
 		$this->mappings[] = $mapper;
 	}
 
-	public function map(string $location, string $typeName, $value) {
+	public function map(string $location, string $typeName, mixed $value): mixed {
 		if ($value === NULL) {
 			return NULL; // todo: really do not translate?
 		}
@@ -44,14 +44,7 @@ final class TypeMapper
 		throw CouldNotMapTypeException::didYouRegisterTypeMapperFor($typeName, $value);
 	}
 
-	private function getTypeForValue($value): string {
-		return !\is_object($value) ? \gettype($value) : \get_class($value);
-	}
-
-	/**
-	 * @return string|Type
-	 */
-	public function mapType(string $location, string $typeName)
+	public function mapType(string $location, string $typeName): string|Type
 	{
 		foreach($this->matchers as $idx => $matcher) {
 			if ( ($translatingType = $matcher($typeName, $location)) !== NULL) {
diff --git a/src/exceptions.php b/src/exceptions.php
index 6e10e016ae0c869bdfba1aeaed617b6823febcf4..405d957461b58f38a46a0a0dc4f171086f1ce3fb 100644
--- a/src/exceptions.php
+++ b/src/exceptions.php
@@ -21,7 +21,7 @@ final class ProbablyBrokenPrimaryIndexImplementation extends UsageException {
 final class CouldNotMapTypeException extends UsageException
 {
 
-	public static function didYouRegisterTypeMapperFor(string $typeName, $value): self
+	public static function didYouRegisterTypeMapperFor(string $typeName, mixed $value): self
 	{
 		return new self(
 			"Did you register type mapper for type '$typeName' and value of type "