I declared a variable called last_shot and initialized it to the value returned by Time.get_ticks_msec()
then, I had a constant variable that specified the cooldown time, in milliseconds (for example, 500 for half a second)
finally, when the player wants to shoot, you get the difference between last_shot and the value returned by Time.get_ticks_msec() in that specific moment. If it is bigger than the cooldown time, the player can shoot and last_shot is updated to Time.get_ticks_msec(). Otherwise, do not shoot and leave last_shot unchanged
I generally have a Timer called GunCooldown already in the scene with the Wait time already set, and a variable like can_shoot : bool = true at the top of my script. Where I deal with input has
if Input.is_action_just_pressed("shoot") and can_shoot:
shoot()
And then the shoot function
func shoot() -> void:
can_shoot = false
$GunCooldown.start()
# spawn the bullet
var b = bullet_scene.instantiate()
get_tree().root.add_child(b)
$ShootSound.play()