0

I have something like this:

function createProxy ( configObj ) {
  //...some code
  return new Proxy({}, {
    get: ( target, name ) => {
      // ...does things
      return Reflect.get(target, name);
    },
     set: function(target, name, value){
      // ...does things
      return Reflect.set(target, name, value);
    },
  }
}

I have to use "new" keyword for utilizing this function and this is how I use it:

const proxy = new createProxy({ someConfig: string })
proxy.foo = 'bar'

And I have declared this module like this:

declare module 'create-proxy' {
  declare class createProxy {
    constructor(config: { someConfig?: string })
    [ index: string ]: string
  }  
  export { createProxy }
}

And I have no type errors. But...

I have two concerns about this (I am new to Typescript module declaration, my typing can be totally wrong, and that is exactly what I need help about. I have read all the related Typescript docs but couldn't solve it on my own. I just need an experienced person to show me the way),

1- [index: string]: string seems too generic to me and my initial thought was "I think I should define the types of get and set methods of proxy somewhere in my declaration to be able to shape the type of indexable properties. I just feel it needs something more but I am not really experienced declaring modules and I can't point my finger at the problem.

2- What this module exports is actually a function that I need to call with the new keyword but what I am declaring is a class. That is because I have tried declaring it as a function but then I would get the type error saying that this function does not have a constructor (Because I am calling it with the new keyword when I am utilizing the function). I feel this is off, too.

Could you give me a hand here, please? Am I too confused or on the right path?

typescript 3.8.3

dugong
  • 3,690
  • 4
  • 11
  • 27
  • "*I have to use "new" keyword for utilizing this function*" - no. What made you think that? – Bergi May 10 '20 at 16:04
  • @Bergi That is the use of it in this case. I haven't created this function which my example above is just a shortened mock of it, and I need to declare a typescript module for it. – dugong May 10 '20 at 18:26
  • I don't think there's enough information here to advise you on your first question: what is the relationship between the passed-in `config` parameter to the constructor and the object that comes out? The example code doesn't seem to be complete enough to give an idea what property names are and are not accepted. – jcalz May 10 '20 at 19:47
  • @Ege It would be better if your question could show that you actually need to use `new`. But to actually answer your question, no, you don't need to declare a `class`: https://stackoverflow.com/q/39622778/1048572 https://stackoverflow.com/q/45462476/1048572 – Bergi May 10 '20 at 21:37
  • @jcalz - Thank you for trying to help, there is no direct relation between a property name and config file. Config file is used to decide whether to do A or B when the properties are reached by the user. That is happening in the `get` method of the Proxy. All string form properties are accepted, thought they are modified before they are shown to the user depending on the config object. Given that, do you think my typing is sufficient enough to declare this module? – dugong May 11 '20 at 13:11
  • Hey @Bergi, thanks! This stackoverflow thread doesn't really help, it assumes I am passing a class to the function, but here I need to call the function with the new keyword. I still need to declare the class. If you know how to shape this without the class declaration, could you please share a code snippet so I can learn? – dugong May 11 '20 at 13:19
  • @Ege No, these threads just show the syntax for how to declare an interface for something that needs to be called with `new` - such as a `class` constructor *or your function*. No, you do not need to declare a class. – Bergi May 11 '20 at 14:09
  • @Bergi I understand your claim but that thread is not showing anything helpful in my case. It assumes you are passing the class to the function. I am trying to call the **function** with the `new` keyword. This is more like what I am trying to achieve: https://github.com/Microsoft/TypeScript/issues/2299 – dugong May 11 '20 at 14:40
  • 1
    If all you know about the class instances is that it will have a `string` value for every possible key then you are probably doing the best you can do here. Maybe `string | undefined` instead of `string` if you want users to be more careful? So I'd say this is "on the right path" given the info I have. Not sure that warrants an answer though, or even a programming SO question as opposed to a question on [Code Review Stack Exchange](https://codereview.stackexchange.com/)... – jcalz May 11 '20 at 14:45
  • @Ege The syntax for the type is the same whether in a parameter of another function or for a variable declaration. You want `declare var createProxy { new(config: …): … }` – Bergi May 11 '20 at 14:46
  • @Bergi This is not helpful. I don't think your code piece here ^ is a valid Typescript. – dugong May 11 '20 at 17:58
  • 1
    @Ege Is that not how you declare the type of a variable (without creating the variable itself) in TypeScript? Edit: Ah, I guess I forgot the colon. `declare var createProxy: { new(config: …): … };` – Bergi May 11 '20 at 18:06
  • @Bergi Ahh, that is a subtle change but now I understand, thank you. And this works as the class declaration above in my question. However, now with this code I am declaring a var, not a function. My original issue was the question of whether I can declare a function that I can call with `new` keyword in Typescript. If I apply this approach as this: `declare function Foo( config: ConfigType ): { new ( config: ConfigType ): FooInterface }` it throws `'new' expression, whose target lacks a construct signature` error. Do you know any idea why? – dugong May 11 '20 at 18:46
  • @Ege I don't think there's any difference between declaring a `var` with a function type and a `function`. Besides, your `createProxy` that requires to be called with `new` is not a normal function anyway. – Bergi May 11 '20 at 19:30

0 Answers0