Skip to content

Commit

Permalink
perf: Offload private check to Typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
Alorel committed Dec 7, 2023
1 parent a2d1ce8 commit dbeb2c7
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 34 deletions.
14 changes: 5 additions & 9 deletions src/index.ts
@@ -1,8 +1,8 @@
interface Ctx<T, A extends any[], R> extends Omit<ClassMethodDecoratorContext<T, Fn<T, A, R>>, 'private'> {
private: false;
}
type Fn<T, A extends any[], R> = (this: T, ...args: A) => R;
type Decorator<T, A extends any[], R> = (
target: any,
ctx: ClassMethodDecoratorContext<T, Fn<T, A, R>>
) => void;
type Decorator<T, A extends any[], R> = (target: any, ctx: Ctx<T, A, R>) => void;

function nameFn<T extends {name: string}>(value: string, fn: T): T {
Object.defineProperty(fn, 'name', {
Expand All @@ -17,14 +17,10 @@ function nameFn<T extends {name: string}>(value: string, fn: T): T {
function BoundMethod<T, A extends any[], R>(): Decorator<T, A, R>;
function BoundMethod<T, A extends any[], R>(...args: Partial<A>): Decorator<T, A, R>;
function BoundMethod<T, A extends any[], R>(...args: Partial<A>): Decorator<T, A, R> {
return function boundMethodDecorator(origFn: Function, {addInitializer, name, private: isPrivate}) {
return function boundMethodDecorator(origFn: Function, {addInitializer, name}) {
const sName = String(name);
const boundName = `Bound(${sName})`;

if (isPrivate) {
throw new Error('Can\'t make private methods bound');
}

const performBind: (inst: T) => Fn<T, A, R> = nameFn(
`BoundMethodBinder(${sName})`,
args.length
Expand Down
25 changes: 0 additions & 25 deletions src/test.ts
Expand Up @@ -6,12 +6,6 @@ import {BoundMethod} from './index';
const STATIC_MUL = 2;
const src: number[] = [-5, 0, 1, 5, 10];

function checkPrivate(clazz: () => any): void {
it('Should disallow decorating private methods', () => {
expect(clazz).to.throw('Can\'t make private methods bound');
});
}

describe('Static', () => {
class Foo {
public static readonly multiplier = 10;
Expand All @@ -28,16 +22,6 @@ describe('Static', () => {
}


// noinspection JSUnusedGlobalSymbols
checkPrivate(() => class {
public static x() {
this.#x();
}

@BoundMethod()
static #x() {}
});

it('as is', () => {
expect(src.map(Foo.asIs)).to.deep.eq(src.map(v => v * Foo.multiplier));
});
Expand Down Expand Up @@ -68,15 +52,6 @@ describe('Instance', () => {
inst = new Foo();
});

checkPrivate(() => class {
public constructor() {
this.#x();
}

@BoundMethod() // eslint-disable-line class-methods-use-this
#x() {}
});

it('as is', () => {
expect(src.map(inst.asIs)).to.deep.eq(src.map(v => v * inst.multiplier));
});
Expand Down

0 comments on commit dbeb2c7

Please sign in to comment.