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: 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`