Typescript's union types are really nice for writing interpreters.
type Value = NumberValue | StringValue;
function add(array<Value> args): NumberValue { ... }
I often find that primitive functions get little checking (e.g. just returning a Value) in the host language.