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.