How to make water in a platformer?

I already know how to use Tiled, tilemaps and tilesets. I just don’t get how I’m supposed to handle the creation of water game objects and apply the collision physics. When the player touches and swims through the water some water blocks don’t have collision and the player can just skip through the top of the water.

Right now I’m just looping through the tiles in tilemap layer that has the water tiles in it and adding new water game objects to a group where I add a collider against the player:

const water = this.add.group();

this.physics.add.collider(this.player, water, function(objectA: GameObject, objectB: GameObject)
{
    objectB.onCollide(objectA);
});

groundLayer.forEachTile((tile: Phaser.Tilemaps.Tile) =>
{
    if(tile.index > 82 && tile.index < 93)
    {
        tile.alpha = 0.8;
        water.add(new Water(this, tile.pixelX, tile.pixelY));
    }
});

Water class stuff:

export default class Water extends StaticGameObject
{
    constructor(scene: PlanetLogicScene, x: number, y: number)
    {
        super(scene, x, y, "water");

        scene.physics.add.existing(this);

        this.setMaxVelocity(0, 0);
        this.setOrigin(0, 0);
        this.setSize(this.displayWidth, this.displayHeight);
        this.setVisible(false);
    }

    public onCollide(object: Lifeform)
    {
        object.inLiquid = true;
    }
}  

// Other code:

export default class StaticGameObject extends Phaser.Physics.Arcade.Image
{
    constructor(scene: Phaser.Scene, x: number, y: number, texture: string | Phaser.Textures.Texture, frame?: string | integer, solid?: boolean)
    {
        super(scene, x, y, texture, frame);
        scene.add.existing(this);
    }

    public onCollide(object: GameObject) 
    {

    }

    // Code...
}

This is how I’m handling the water physics:

export default class Lifeform extends GameObject
{
    // Code...
  
    public inLiquid: boolean = false;
    public isOnSlope: boolean = false;
    public wasInLiquid: boolean = false;
    public wasOnSlope: boolean = false;
    
    private isJumping: boolean = false;
    protected jumpSpeed: number = 80;
    protected jumpHeight: number = 310;

    protected xSpeed: number = 8;
    protected maxVel: { x: number, y: number} = { x: 175, y: 600};
    protected drag: { x: number, y: number} = { x: 30, y: 0};
    protected xDeacl: number = 10;
    protected xDeaclInAir: number = 3;
    protected ySwimSpeed: number = 140;
    protected maxVelInWater: number = 75;

    protected resetPhysics()
    {
        return this.setDrag(this.drag.x, this.drag.y).setMaxVelocity(this.maxVel.x, this.maxVel.y);
    }


    public preUpdate(time: number, delta: number)
    {
         // Code ...

        const onGround = this.body.blocked.down || this.isOnSlope;

        if(this.controls.left())
        {
            this.setVelocityX(this.body.velocity.x - this.xSpeed);
        }
        if(this.controls.right())
        {
            this.setVelocityX(this.body.velocity.x + this.xSpeed);
        }
        if(!this.controls.left() && !this.controls.right())
        {
            const xDeacl = onGround ? this.xDeacl : this.xDeaclInAir;

            if(this.body.velocity.x > 0)
            {
                this.setVelocityX(this.body.velocity.x - xDeacl);
            }
            if(this.body.velocity.x < 0)
            {
                this.setVelocityX(this.body.velocity.x + xDeacl);
            }

            if(Math.abs(this.body.velocity.x) < xDeacl)
            {
                this.setVelocityX(0);
                this.anims.play("idle");
            }
        }

        if(this.inLiquid)
        {
            if(this.controls.up())
            {
                this.setVelocityY(-this.ySwimSpeed);
            }
            else if(this.controls.down())
            {
                this.setVelocityY(this.ySwimSpeed);
            }
        }
        else if(onGround && this.controls.up())
        {
            this.isJumping = true;
        }

        if(!this.controls.up() || this.body.velocity.y < -this.jumpHeight)
        {
            this.isJumping = false;
        }
  
        if(this.isJumping)
        {
            this.body.velocity.y -= this.jumpSpeed;
        }

        const onCeiling = this.body.blocked.up;

        if(onCeiling)
        {
            this.isJumping = false;
            this.body.velocity.y = 0;
        }

        if(this.inLiquid)
        {
            this.setMaxVelocity(this.maxVelInWater);
            this.setGravity(0);
        }
        else
        {
            this.resetPhysics();
        }

        (this.body as Phaser.Physics.Arcade.Body).setAllowGravity(!this.isOnSlope);
    
        this.wasInLiquid = this.inLiquid;
        this.wasOnSlope = this.isOnSlope;
        this.isOnSlope = false;
        this.inLiquid = false;

         // Code ...
    }

    // Code...
}

I honestly have no idea what the problem is. I just know some water blocks don’t have collision. That’s it.

If anyone can figure this out I’ll be extremely surprised.