sirisian / ecmascript-types

ECMAScript Optional Static Typing Proposal http://sirisian.github.io/ecmascript-types/
453 stars 4 forks source link

Typed Record and Tuple section #56

Open sirisian opened 3 years ago

sirisian commented 3 years ago

https://github.com/tc39/proposal-record-tuple

This is just random notes. Feel free to comment with the correct syntax. The big picture is to type the data in the Record and Tuple with native types.

interface IPoint { x:int32, y:int32 }
const ship1:IPoint = #{ x: 1, y: 2 };
// ship2 is an ordinary object:
const ship2:IPoint = { x: -1, y: 3 };

function move(start:IPoint, deltaX:int32, deltaY:int32):IPoint {
  // we always return a record after moving
  return #{
    x: start.x + deltaX,
    y: start.y + deltaY,
  };
}

const ship1Moved = move(ship1, 1, 0);
// passing an ordinary object to move() still works:
const ship2Moved = move(ship2, 3, -1);

console.log(ship1Moved === ship2Moved); // true
// ship1 and ship2 have the same coordinates after moving

(I used int32 above because I assume float32 and floating point comparisons aren't really supposed to be used with Record).

const measures = #[uint8(42), uint8(12), uint8(67), "measure error: foo happened"];

// Accessing indices like you would with arrays!
console.log(measures[0]); // 42
console.log(measures[3]); // measure error: foo happened

// Slice and spread like arrays!
const correctedMeasures = #[
  ...measures.slice(0, measures.length - 1),
  int32(-1)
];
console.log(correctedMeasures[0]); // 42
console.log(correctedMeasures[3]); // -1

// or use the .with() shorthand for the same result:
const correctedMeasures2 = measures.with(3, -1);
console.log(correctedMeasures2[0]); // 42
console.log(correctedMeasures2[3]); // -1

// Tuples support methods similar to Arrays
console.log(correctedMeasures2.map(x => x + 1)); // #[43, 13, 68, 0]

How do you type variadic Tuples when returning them from a function? I have no idea.

function F():#[...uint8, string, ...uint32] {
  return #[
    ...[0, 1, 2],
    'a',
    ...[3, 4, 5]
  ];
}

Random scribbles:

Record:

interface ITuple [string, string, string, string, string]
interface IRecord {
  a:uint8,
  b:string,
  c:string,
  d:ITuple
}
const r:IRecord = #{
  a: 1,
  b: 'b',
  c: `...`,
  d: #['a', 'b', 'c', 'd', 'e']
};
const r = #{
  a: uint8(1),
  b: 'b',
  c: `...`,
  d: #['a', 'b', 'c', 'd', 'e']
};

Tuple:

interface ITuple [uint8, uint8, uint8, string]
const t:ITuple = #[0, 1, 2, 'a'];
const t = #[uint8(0), uint8(1), uint8(2), "a"];