function checking type of input and reacting
The result of pg_typeof() is an oid, if you want to compare that with a string value, you need to cast it, e.g. if pg_typeof($1)::text = 'jsonb' then... 

But once you checked if the input is a JSON you also need to verify if it's a JSON array, because {"foo": "bar"} will also be reported as json(b).

The way you iterate over the array is also quite inefficient as you are running the same select statement over and over again. You can check this with a single statement. 

There is no ELIF in PL/pgSQL. As documented in the manual it needs to be ELSIF

So the function would look something like this: 

CREATE OR REPLACE FUNCTION check_is_animal(anyelement) 
  RETURNS boolean 
AS $$
DECLARE
   arr text[];
   l_result boolean;
BEGIN
  -- check if the argument is a text array
  -- this could be expanded to check for character varying[] as well
  IF pg_typeof($1)::text = 'text[]' THEN
    arr := $1;
  ELSEIF pg_typeof($1)::text = 'jsonb' THEN
    IF jsonb_typeof($1) = 'array' THEN
      -- check if the array contains strings or objects:
      IF jsonb_typeof($1 -&gt; 0) = 'object' THEN
        -- assuming the key is always name:
        arr := array(select jsonb_array_elements($1) -&gt;&gt; 'name');
      ELSE 
        arr := array(select jsonb_array_elements_text($1::jsonb));
      END IF;
    ELSE 
      return false;
    END IF;
  ELSEIF pg_typeof($1)::text = 'json' THEN
    IF json_typeof($1) = 'array' THEN
      arr := array(select jsonb_array_elements_text($1::jsonb));
    ELSE 
      return false;
    END IF;
  ELSE 
    -- no array whatsoever 
    return false;
  END IF;

  select count(*) = 0
    into l_result
  from unnest(arr) as x(name)
  where not exists (select *
                    from animals a
                    where x.name = a.animal);

  return l_result;
END;
$$ LANGUAGE plpgsql;


If the JSON array contains unknown key names and you can't use the hardcoded name, you can use this instead:

    arr := array(select x.v
                 from jsonb_array_elements($1) as t(e) 
                 cross join jsonb_each_Text(t.e) as x(k,v));


The final select statement checks if all elements in the array exist in the table. By using a NOT EXISTS condition, the statement can stop as soon as one non-existing animal is found.

Online example