Rather than having is_odd return its result as its status-code, I think it's better to print its result:
is_odd()
{
expr $1 % 2
}
Then you can use command-substitution (`...` or $(...)) to get the result:
echo -e $in " is an " ${type[$(is_odd $in)]} " number."
Though to be honest, in this specific case I'd probably just get rid of the function and use the arithmetic expression directly — and probably adjust the quoting a bit for readability:
echo -e "$in is an ${type[in % 2]} number."
(Note that double quotes "..." do not prevent parameter substitution ${...}. Only single-quotes '...' and backslashes \ do that. Also, hat-tip to jordanm for pointing out that array indices are automatically treated as arithmetic expressions, even without expr or ((...)) or whatnot.)
That said, if you really want to return 1 for "odd" and 0 for "even", then firstly, you should rename your function to is_even (since in Bash, 0 means "successful" or "true" and nonzero values mean "error" or "false"), and secondly, you can use a follow-on command to print its return value, and then use command-substitution. Either of these should work:
echo -e "$in is an ${type[$(is_even $in ; echo $?)]} number."
echo -e "$in is an ${type[$(is_even $in && echo 0 || echo 1)]} number."
(By the way, I've also changed a to an in all of the above examples: in English it's "an odd number", "an even number".)