How to create 2 incompatible numeric types in TypeScript?

I am trying to figure out how to create 2 mutually supportive numeric / integer types in TS.

For example, in the code below, height and weight are both numerical, and the concept of adding them together or their equivalent processing is meaningless and should be a mistake.

type height = number; // inches
type weight = number; // pounds
var a: height = 68;
var b: weight = operateScale(); // Call to external, non-TS function, which returns a weight.
console.log(a+b); // Should be an error.

Is there a way to create 2 types that are both numbers but not compatible with each other?


EDIT: As mentioned in the comments section, this behavior is similar to haskell behavior newtype.


EDIT2: after several hours of concussion with a pointed stick problem, I managed to find the answer that I posted below.

+4
source share
2 answers

, :

class height extends Number {}
class weight extends Number {}

Number, Typescript .

, .

var a: height = 68;
var b: weight = 184;
console.log(a+b); // Should be an error.

, , , :

console.log(a+a); // Should NOT be an error.
-1

newtype TypeScript "" (TypeScript , , ) , . :

interface Height { 
  __brand: "height"
}
function height(inches: number): Height {
  return inches as any;
}
function inches(height: Height): number {
  return height as any;
}

interface Weight { 
  __brand: "weight"
}
function weight(pounds: number): Weight {
  return pounds as any;
}
function pounds(weight: Weight): number {
  return weight as any;
}

const h = height(12); // one foot
const w = weight(2000); // one ton

Height Weight (, ) . height() Height ( number a Height), inches() ( Height a number), weight() pounds() - Weight. - . JavaScript , , , , , :

const h = 12 as any as Height;
const w = 2000 as any as Weight;

, , Height, Weight . , newtype, number. , Height Weight number ( ), , , : + number, h w number, h + w . h w number, h + h . , TypeScript , . h + h, h + w, Height Weight number s. add(), , :

type Dimension = Height | Weight;

function add<D extends Dimension>(a: D, b: D): D {
  return ((a as any) + (b as any)) as any;
}

add() Height Weight . , , - Height | Weight D, , , :

function add(a: Height, b: Height): Height;
function add(a: Weight, b: Weight): Weight;
function add(a: any, b: any): any {
  return a+b;
}

,

const twoH = add(h, h); // twoH is a Height
const twoW = add(w, w); // twoW is a Weight
const blah = add(h, w); // error, Height and Weight don't mix

, . measureScale() Weight:

declare function measureScale(): Weight;

var a = height(68);
var b = measureScale();

:

console.log(add(a,b)); // err
console.log(add(a,a)); // okay

, ; !

0

Source: https://habr.com/ru/post/1691602/


All Articles