public static function from($default) : IType
    {
        switch (gettype($default)) {
            case 'NULL':
                return self::null();
            case 'string':
                return self::string();
            case 'integer':
                return self::int();
            case 'double':
                return self::float();
            case 'boolean':
                return self::bool();
            case 'array':
                if (count($default) < 20) {
                    $types = [];
                    foreach ($default as $value) {
                        $types[] = self::from($value);
                    }
                } else {
                    $types = null;
                }

                return self::arrayOf($types ? UnionType::create($types) : self::mixed());
            case 'object':
                if ($default instanceof ITypedCollection) {
                    return self::collectionOf($default->getElementType(), get_class($default));
                } else {
                    return self::object(get_class($default));
                }
        }

        throw InvalidArgumentException::format(
                'Unknown type: %s', Debug::getType($default)
        );
    }