0

This is closely related to How does Chai JS make function parentheses optional?, but not quite identical. Make the parentheses in function calls optional also seems similar, but the second link isn't using Object.defineProperty and the first link makes it such that it is mandatory to not include parenthesis.

Essentially, what I'm trying to accomplish is having both a method and a getter with the same name, or a getter that can take arguments if you add parenthesis.

Note also that I am using Typescript, and I want to make sure my typings don't get funky due to whatever solution is used.

I am thinking, for example, of how with the Chai library, both of these are valid:

  • expect(foo).to.be.undefined
  • expect(foo).to.be.undefined('some message')

I've tried this:

let foo = Object.defineProperty(
    { test: (f: string = 'get') => console.log(f) },
    'test',
    { get: () => console.log('get') }
);
foo.test
foo.test('value')

But while this approach makes vscode's intellisense happy, I get an error at runtime. Weirdest part is that at runtime it seems like it's calling the getter twice, but the second time also produces an error about test not being a function: enter image description here

I've poked around in Chai's source code, and while they use Object.defineProperty liberally, I'm having trouble tracking down exactly how they make things like both .undefined and .undefined(message) work.

user3534080
  • 1,201
  • 1
  • 14
  • 21
  • Have a look at the source code for [addProperty](https://github.com/chaijs/chai/blob/4.x.x/lib/chai/utils/addProperty.js#L38) – Phil Jun 30 '23 at 05:49
  • @Philisonstrike that looks almost exactly the same as my code blurb above. adding `configurable: true` didn't seem to change the behavior I was seeing, nor did using `.call(this)`. Am I missing something? – user3534080 Jun 30 '23 at 15:10
  • After about 4 hours of poking around Chai's code, there appears there's some other secret sauce somewhere in Chai. `Assertion.addProperty('foo', (s='get')=>{console.log(s)})` does not allow parenthesis, but `Assertion.addProperty('foo', (s='get')=>{console.log(s); this.assert(false, 'pass', 'fail')})` does. This might be due to the `proxify` method, but I don't think so... still clueless on how to generalize this outside assertions. – user3534080 Jun 30 '23 at 20:26

0 Answers0