Description
I don't know if "derived" is the correct term, but, currently, I can do something like this:
type UserID = number;
type Timestamp = number;
var id = <UserID> 123;
var time = <Timestamp> 12345678;
var nonsense = id + time;
The problem is obvious - different types of IDs (all numbers) and even completely unrelated datatypes (such as timestamps) are all interchangeable; there is no type-safety for different types of data that all happen to be integers.
I would like to be able to do something along the lines of this:
type UserID: number;
type Timestamp: number;
var id = <UserID> 123;
var time = <Timestamp> 12345678;
var nonsense = id + time; // ERROR
The difference here, is that UserID
and Timestamp
are actually distinct types derived from a base type (in this case a primitive), not just aliases of number
.
The derived type is similar to the type it was derived from - it has all of the same members.
It can be safely cast back to the type it was derived from, for example:
type UserID: number;
var user_id = <UserID> 123;
var id: number = user_id; // VALID
You cannot however automatically cast back up:
var id = 123;
var user_id: UserID = id; // ERROR
But you can of course do so with an assertion:
var id = 123;
var user_id = <UserID> id; // VALID
In other words, UserID
is always a number
, but number
is not necessarily a UserID
.
Another example might be a point type:
class Point {
x: number;
y: number;
}
type Centroid: Point;
var center: Centroid = { x: 1.234, y: 2.345 };
var p: Point = center; // VALID
var oops: Centroid = p; // INVALID
Again, a Centroid
is always a Point
, but a Point
is not a Centroid
unless you make that assertion.
In short, this feature enables static type-checking of types that are technically identical - there is only one implementation, but there is more than one meaning.
Other examples might be "email", "phone number", "credit card", "IP address" and "hex color code", which are all strings, each with a particular meaning, all of which can be treated as strings, but none of which are interchangeable in any meaningful way.