-2

Looking at

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy

In TypeScript in Strict mode, I tried,

const handler = {
    get: (obj:object, prop:string) => prop in obj
        ? obj[prop] //Error here
        :37     
};

const p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37

and getting error:

[ts] Element implicitly has an 'any' type 
because type '{}' has no index signature.
(parameter) prop: string

What is the most concise and proper way to resolve thi issue?

This answer https://stackoverflow.com/a/47461946/1028880 might be related, but not sure. Thanks.

  • 3
    Add index typing: `get: (obj: {[key: string]: any}, prop: string) ....` – Aleksey L. Jul 30 '18 at 09:17
  • Related: https://stackoverflow.com/q/42193262/457268 – k0pernikus Jul 30 '18 at 09:25
  • @AlekseyL. 's answer is identical to Titian Cernicova-Dragomir's first answer/ It is great to be able to double check the consistency. thanks a lot. –  Jul 30 '18 at 10:22
  • @k0pernikus Thanks, it's hard to interpretr class thing to functional, tougnh. –  Jul 30 '18 at 10:24

1 Answers1

1

It depends on what you are trying to do, one option is to add an index signature to the parameter:

const handler = {
    get: (obj: { [n: string]: any }, prop:string) => prop in obj
        ? obj[prop] //ok
        :37     
};

const p = new Proxy<any>({}, handler); // if no known shape exists for the object and we want to add anything to it we can use any
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37

Another option is to use generics and keyof:

const handler = {
    get: <T>(obj: T, prop:keyof T) => prop in obj
        ? obj[prop] //also ok
        :37     
};

const p = new Proxy<{ a?: number, b?: string, c?: number}>({}, handler); // we can also add a more restrictive type to the proxy if we have an idea of the shape of the object
p.a = 1;
p.b = undefined;

console.log(p.a, p.b); // 1, undefined
console.log('c' in p, p.c); // false, 37
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • Thanks a lot as usual, the different approach presented is really cool. I wonder how you and others have got this knowledge. From typescript official documents of the site and any other online resources or books? –  Jul 30 '18 at 10:27
  • @bayesian-study Answering questions on SO, and reading the GitHub pull requests :) – Titian Cernicova-Dragomir Jul 30 '18 at 10:30
  • Oh, you mean the pull requests to TypeScript GitHub repo? cool. –  Jul 30 '18 at 10:35
  • @bayesian-study Yup, you'll find the important ones in the roadmap: https://github.com/Microsoft/TypeScript/wiki/Roadmap. But I have been following typescript since 0.9 so I have a bit of a head start :) – Titian Cernicova-Dragomir Jul 30 '18 at 10:39
  • I see. I also have known from the early stage but stopped following because thought it's a class thing. By the way, speaking of the repo, I had posted another question which is basically about self-reference type implementation in TypeScript https://stackoverflow.com/questions/51575722/in-typescript-is-there-any-method-to-type-function-return-values-to-the-functio and someone answered it's possible by conditional types. Is it even true? –  Jul 30 '18 at 11:02
  • @bayesian-study I'll have a look, I saw the question but I try not to answer long questions on weekends, weekends are family time, mostly :) – Titian Cernicova-Dragomir Jul 30 '18 at 11:13
  • @bayesian-study It's still to long.. I think it can be done but I don't have time to look at it right now – Titian Cernicova-Dragomir Jul 30 '18 at 11:19
  • Sure, thanks. When you have time to answer, I'm grateful. –  Jul 30 '18 at 11:45