I just realised that I should probably give a little more context.
I think it is key to understand that
numba.float64[...] is not itself a type but a cleverly disguised call to the
__getitem__ function of numba.float64. This call returns the actual type and does not work inside jitted code as far as I can tell.
The reason it works in the function signature is that it the function call to
numba.float64__getitem__ is evaluated at definition time and not at call time (this is a common misunderstanding surrounding python).
That means by the time numba sees that type in the signature, it has already been evaluated and the actual type has been returned. That is also why it is possible to define the type outside the function and then use it as a constant.
In : _T_F8_ARRAY
Out: array(float64, 1d, A)
In : numba.float64.__getitem__
Out: <bound method Type.__getitem__ of float64>
In : ?numba.float64.__getitem__
Docstring: Return an array of this type.