简体   繁体   中英

TypeScript: define dynamic properties in proxy

I have the following call to a watch

const watch = hp.watch({
  running: false,
  time: 0,
  start: Date.now()
})

watch bassically just runs new proxy() , then sets some properties and returns the newly created proxy class nothing too fancy.

export function watch(item: { [key: string]: any }): proxy
export function watch(key: string, value: any): proxy
export function watch(...args: any[]): proxy {
  let prox = new proxy()
  if (args.length == 2) {
    prox[args[0]] = args[1]
  } else if (args.length == 1 && args[0] instanceof Object) {
    for (let itm in args[0]) {
      !(itm in prox) && (prox[itm] = args[0][itm])
    }
  }
  return prox
}

I then have an interface which looks like this:

export interface proxy {
  [key: string]: any
}

Here is the the proxy class which basically is just a wrapper.

namespace hp {
  export class proxy {
    public constructor() {
      return new Proxy(this, { /* Proxy stuff */})
    }
  }
}

In an editor that supports intellisense, it would be nice if I could have it suggest running , time , start after I type watch. .

I think I need to use a more advanced interface (or type ) than the one I am using for that to happen. I have tried this but it doesn't work:

export type watch<T> = {
  [A in keyof T]: T[A]
} 

export interface proxy {
  [key: string]: watch<any>
}

When doing watch.time = 123 I get an error stating:

Type 'number' is not assignable to type 'watch'.

and when trying to get the value let a = watch.time I get this error:

The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.

You want to change the signature for hp.watch() to something like

export function watch<T>(item: T): proxy & T;
export function watch<K extends string, V>(key: K, value: V): proxy & Record<K, V>;
export function watch(...args: any[]): proxy {
  // impl
}

Then you have told TypeScript that the output of the function is both a proxy and has the same keys and value types as the thing you passed in.

Hope that helps; good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM