sens
g/CozienaProfdyuktywnoscINfrmtyczn

Ujdzie, czy przesada i dzwonicie po policję? XD

Chciałem sobie otypować grupę podobnych metod i po prostu użyć dekoratorów jak normalny człowiek, które co prawda w TS są trochę upierdliwe, ale da się je doprowadzić do działania. Tylko potem zmusić TS do wykminienia, jaki jest typ udekorowanej metody to jednak jest trochę koszmar, więc spłodziłem takie gówno.

W pythonie jakoś sobie poradzili z tym sprawniej, ale pewnie mieli łatwiej, bo dosłownie wszystko jest obiektem, a w JS to null niby jest prymitywną wartością, ale typeof null === 'object' zwraca true i nie są tego w stanie naprawić od 30 lat, bo internet by wybuchł xd

export const vecOp = <T>(op: (this: Vec, v: IVec) => T) => {
  function wrapped(this: Vec): T
  function wrapped(this: Vec, v: IVec): T
  function wrapped(this: Vec, x?: number, y?: number): T
  function wrapped(this: Vec, vx?: IVec | number, y?: number) {
    return op.apply(
      this,
      typeof vx === 'number'
        ? [{ x: vx, y: y ?? 0 }]
        : vx === undefined
        ? [{ x: 0, y: 0 }]
        : [vx],
    )
  }
  return wrapped
}

export class Vec implements IVec {
  add = vecOp(v => new Vec(this.x + v.x, this.y + v.y))
  sub = vecOp(v => this.add(-v.x, -v.y))
  dot = vecOp(v => this.x * v.x + this.y * v.y)
  dist = vecOp(v => this.sub(v).norm)

#
sens

@sens: aha, jak powyższe nie wywołuje u was odruchu wymiotnego, to co powiecie na emulację przeciążania operatorów używając template tagów? XD

export class Vec implements IVec {
   static expr(ops: TemplateStringsArray, ...args: any[]): Vec | number;

A po dopisaniu jakiegoś prostego shunt yarda można sobie używać takiego lukru składniiwgo :--DD

const u = new Vec(2, 1)
const v = new Vec(3, 7)
const p = Vec.expr​​​`|${u} - ${v}|^2​`

#