NEST by default has great support for contravariant results of the documents you store
So if you do
Index<B>()
Index<C>()
Index<D>()
And then do a search for Search<A>(s=>s.Types(B,C,D))
given that all of them derive from A you will get an IEnumerable result with actual instances of B, C and D inside of it.
To get contra/covariance going inside your own document you'll have to do the wiring yourself.
You will have to register a custom jsonconverter on the property to make sure JSON.net deserializes the json back to the actual subtype instead of the supper.