My idea of an ideal solution is the introduction of the possibility to use "any" pseudotype as return type with possibility to set default return type. Now, "any" is allowed only for arguments. The planner can set the expected type when it knows it, or can use the default type.
so for extraction of jsonb field we can use FUNCTION jsonb_extract_field(jsonb, text) RETURNS "any" DEFAULT jsonb
Is this an existing framework or do you want to create something new?
if we call SELECT jsonb_extract_field(..., 'x') -> then it returns jsonb, if we use SELECT jsonb_extract_field('...', 'x')::date, then it returns date
If so, what is the difference from the current jsonb->'f' and (jsonb->'f' )::date?
With this possibility we don't need to touch to cast functions, and we can simply implement similar functions for other non atomic types.
What do you mean by "atomic type" here? If you want to introduce some new framework, I think we need a very clear benefit.