This workaround not works
CREATE FUNCTION json_array_castext(json) RETURNS text[] AS $f$
SELECT array_agg(x::text) FROM json_array_elements($1) t(x);
$f$ L
try json_array_elements_text instead of json_array_elements, and you don't need explicit casting to text (x::text), so you can use:
CREATE or replace FUNCTION json_array_castext(json) RETURNS text[] AS $f$
SELECT array_agg(x) FROM json_array_elements_text($1) t(x);
$f$ LANGUAGE sql IMMUTABLE;
For your additional question
Why x::text is not a cast?
This is cast and because of this, its not giving any error, but when casting json string to text like this: ::text, postgres adds quotes to value.
Just for testing purposes, lets change your function to original again (as it is in your question) and try:
SELECT
(json_array_castext('["hello","world"]'))[1] = 'hello',
(json_array_castext('["hello","world"]'))[1],
'hello'
As you see, (json_array_castext('["hello","world"]'))[1] gives "hello" instead of hello. and this was why you got false when comparing those values.