Interestingly, anything that is not an integer comes back with the given datatype.
stardog query test 'select * where {bind(strdt("test", xsd:nonNegativeInteger) as ?o)}'
"test"^^xsd:nonNegativeInteger
Anything that is an integer comes back as an integer
stardog query test 'select * where {bind(strdt("1", xsd:nonNegativeInteger) as ?o)}'
1
It also behaves similarly for the subtypes xsd:nonPositiveInteger, xsd:long, xsd:nonNegativeInteger. I suspect that it is correct and has something to do with D-Interpretations and Datatype Entailment RDF 1.1 Semantics but I'm not familiar with all the details there.
This is the expected result because Stardog canonicalizes literals. All integer subtypes map to the same value space in the XSD spec so they are equivalent values which is why we do this canonicalization. See the index.literals.canonical option mentioned in [1] and described in more detail at [2]. If you disable this option then all literals will use the assigned types. Note that, without this option your queries will need to use the exact same datatypes to match your data or you'll need to rely on = FILTERs.