If I understood correctly, this may help (the rotation / transformation of the plane won’t really matter in this case) :

const raycaster = new Three.Raycaster();
const cameraPosition = new Three.Vector3();
const pointPosition = new Three.Vector3();
const direction = new Three.Vector3();
camera.getWorldPosition(cameraPosition);
point.getWorldPosition(pointPosition);
direction.copy(pointPosition).sub(cameraPosition).normalize();
raycaster.set(cameraPosition, direction);
const hits = raycaster.intersectObjects([ plane ], true);
if (hits) {
point.position.copy(hits[0].point);
}

If the camera is looking precisely at the point (ie. point is the target of the camera), you can also simplify it by removing direction calculations:

const raycaster = new Three.Raycaster();
const cameraPosition = new Three.Vector3();
const cameraDirection = new Three.Vector3();
camera.getWorldPosition(cameraPosition);
camera.getWorldDirection(cameraDirection); // NOTE We assume camera is looking at the point
raycaster.set(cameraPosition, cameraDirection);
const hits = raycaster.intersectObjects([ plane ], true);
if (hits) {
point.position.copy(hits[0].point);
}

Thank you very much! I didn’t know you can cast rays in any direction, not only from camera.

What I ended up with is the following:

function projectPointOnPlaneTowardsCamera(
point: THREE.Vector3,
plane: THREE.Plane,
camera: THREE.Camera
) {
const direction = new THREE.Vector3();
direction.copy(camera.position).sub(point).normalize();
const ray = new THREE.Ray(point, direction);
return ray.intersectPlane(plane, new THREE.Vector3());
}