Skip to content

Instantly share code, notes, and snippets.

@trueharuu
Created September 20, 2022 16:31
Show Gist options
  • Save trueharuu/5e2322549ac5725e61af79c5c12581dc to your computer and use it in GitHub Desktop.
Save trueharuu/5e2322549ac5725e61af79c5c12581dc to your computer and use it in GitHub Desktop.
type Constructor<U extends Array<unknown>> = new (...args: U) => unknown;
type Keys<T, M = any> = keyof {
[P in keyof T as T[P] extends M ? P : never]: T[P];
};
export class Ops<T = {}> {
public mem: T = {} as never;
public define<K extends string, U>(
key: K,
value: U
): Ops<{
[P in keyof T | K]: [P] extends [K] ? U : P extends keyof T ? T[P] : never;
}> {
this.mem[key as never] = value as never;
return this as never;
}
public remove<K extends keyof T>(
key: K
): Ops<{
[P in keyof T as [P] extends [K] ? never : P]: T[P];
}> {
delete this.mem[key];
return this as never;
}
public access<U extends Keys<T>>(name: U): T[U] {
return this.mem[name];
}
public set<U extends Keys<T>>(name: U, value: T[U]) {
this.mem[name] = value;
return this;
}
public property<U extends Keys<T, object>>(name: U, property: keyof T[U]) {
return Reflect.get(this.access(name as never) as object, property);
}
public call<U extends Keys<T, Function>>(
name: U,
args: Parameters<T[U] extends (...args: any[]) => any ? T[U] : never>
): ReturnType<T[U] extends (...args: any[]) => any ? T[U] : never> {
return (this.access(name as never) as Function)(args);
}
public construct<K extends Keys<T, Constructor<U>>, U extends Array<unknown>>(
name: K,
args: U
): unknown {
return Reflect.construct(
this.access(name as never) as Constructor<U>,
args
);
}
public delete<U extends Keys<T>>(
name: U,
key: keyof {
[P in keyof T[U] as undefined extends T[U][P] ? P : never]: T[U][P];
}
) {
delete this.mem[name][key];
return this;
}
public void<U extends Keys<T>>(name: U): void {
return void this.mem[name];
}
public num(name: Keys<T>): number {
return Number(this.access(name));
}
public neg(name: Keys<T>): number {
return this.num(name) * -1;
}
public bitwiseNot(name: Keys<T, number>): number {
return ~this.access(name as never);
}
public bitwiseAnd(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) &
(this.access(target as never) as number)
);
}
public bitwiseOr(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) |
(this.access(target as never) as number)
);
}
public bitwiseXor(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) ^
(this.access(target as never) as number)
);
}
public bitwiseShiftLeft(
source: Keys<T, number>,
target: Keys<T, number>
): number {
return (
(this.access(source as never) as number) <<
(this.access(target as never) as number)
);
}
public bitwiseShiftRight(
source: Keys<T, number>,
target: Keys<T, number>
): number {
return (
(this.access(source as never) as number) >>
(this.access(target as never) as number)
);
}
public bitwiseShiftRightUnsigned(
source: Keys<T, number>,
target: Keys<T, number>
): number {
return (
(this.access(source as never) as number) >>>
(this.access(target as never) as number)
);
}
public assignBitwiseAnd(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(source as never, this.bitwiseAnd(source, target) as never);
}
public assignBitwiseOr(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(source as never, this.bitwiseOr(source, target) as never);
}
public assignBitwiseXor(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(source as never, this.bitwiseXor(source, target) as never);
}
public assignBitwiseShiftLeft(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(
source as never,
this.bitwiseShiftLeft(source, target) as never
);
}
public assignBitwiseShiftRight(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(
source as never,
this.bitwiseShiftRight(source, target) as never
);
}
public assignBitwiseShiftRightUnsigned(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(
source as never,
this.bitwiseShiftRightUnsigned(source, target) as never
);
}
public ternary<T, U>(condition: Keys<T, boolean>, then: T, el: U): T | U {
return this.access(condition as never) ? then : el;
}
public logicalAnd(
source: Keys<T, boolean>,
target: Keys<T, boolean>
): boolean {
return (
(this.access(source as never) as boolean) &&
(this.access(target as never) as boolean)
);
}
public logicalOr(
source: Keys<T, boolean>,
target: Keys<T, boolean>
): boolean {
return (
(this.access(source as never) as boolean) &&
(this.access(target as never) as boolean)
);
}
public nullishCoalesce<U>(source: Keys<T, U>, target: Keys<T, U>): U {
return (
(this.access(source as never) as U) ?? (this.access(target as never) as U)
);
}
public assignLogicalAnd(
source: Keys<T, boolean>,
target: Keys<T, boolean>
): this {
return this.set(source as never, this.logicalAnd(source, target) as never);
}
public assignLogicalOr(
source: Keys<T, boolean>,
target: Keys<T, boolean>
): this {
return this.set(source as never, this.logicalOr(source, target) as never);
}
public assignNullishCoalesce<U>(
source: Keys<T, U>,
target: Keys<T, U>
): this {
return this.set(
source as never,
this.nullishCoalesce(source, target) as never
);
}
public comma<U>(sources: [...Array<unknown>, U]): U {
return sources.at(-1) as U;
}
public add(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) +
(this.access(target as never) as number)
);
}
public subtract(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) -
(this.access(target as never) as number)
);
}
public multiply(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) *
(this.access(target as never) as number)
);
}
public divide(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) /
(this.access(target as never) as number)
);
}
public modulo(source: Keys<T, number>, target: Keys<T, number>): number {
return (
(this.access(source as never) as number) %
(this.access(target as never) as number)
);
}
public exponentiate(
source: Keys<T, number>,
target: Keys<T, number>
): number {
return (
(this.access(source as never) as number) **
(this.access(target as never) as number)
);
}
public assignAdd(source: Keys<T, number>, target: Keys<T, number>): this {
return this.set(source as never, this.add(source, target) as never);
}
public assignSubtract(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(source as never, this.subtract(source, target) as never);
}
public assignMultiply(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(source as never, this.multiply(source, target) as never);
}
public assignDivide(source: Keys<T, number>, target: Keys<T, number>): this {
return this.set(source as never, this.divide(source, target) as never);
}
public assignModulo(source: Keys<T, number>, target: Keys<T, number>): this {
return this.set(source as never, this.modulo(source, target) as never);
}
public assignExponentiate(
source: Keys<T, number>,
target: Keys<T, number>
): this {
return this.set(
source as never,
this.exponentiate(source, target) as never
);
}
public increment(source: Keys<T, number>) {
this.set(
source as never,
((this.access(source as never) as number) + 1) as never
);
return this;
}
public decrement(source: Keys<T, number>) {
this.set(
source as never,
((this.access(source as never) as number) - 1) as never
);
return this;
}
public greaterThan(
source: Keys<T, number>,
target: Keys<T, number>
): boolean {
return this.access(source as never) > this.access(target as never);
}
public lessThan(source: Keys<T, number>, target: Keys<T, number>): boolean {
return this.access(source as never) < this.access(target as never);
}
public greaterThanOrEqual(
source: Keys<T, number>,
target: Keys<T, number>
): boolean {
return this.access(source as never) >= this.access(target as never);
}
public lessThanOrEqual(
source: Keys<T, number>,
target: Keys<T, number>
): boolean {
return this.access(source as never) <= this.access(target as never);
}
public equal<U>(source: Keys<T, U>, target: Keys<T, U>): boolean {
return this.access(source as never) == this.access(target as never);
}
public inequal<U>(source: Keys<T, U>, target: Keys<T, U>): boolean {
return this.access(source as never) != this.access(target as never);
}
public strictEqual<U>(source: Keys<T, U>, target: Keys<T, U>): boolean {
return this.access(source as never) === this.access(target as never);
}
public strictInequal<U>(source: Keys<T, U>, target: Keys<T, U>): boolean {
return this.access(source as never) !== this.access(target as never);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment