
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`