Skip to content

Derived types #2477

Closed
Closed
@mindplay-dk

Description

@mindplay-dk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions