3

In TypeScript, I can do the following two things:

type ToolboxSpaceType = 'screw'|'hammer'|'screwdriver'; // 1

ProxyProperties = ['screw', 'hammer', 'screwdriver'];  // 2

class Toolbox {
  [key: ToolboxSpaceType]: ToolboxSpace;
}

let proxyHandler = {
  get(target: Toolbox, prop: PropertyKey, receiver: any) {
    if (ProxyProperties.include(prop) {
       //...do something special...
    }
  }
}
let personalToolbox = new Toolbox();
let personalToolboxProxy = new Proxy(personalToolbox, proxyHandler)

I'd like to be able to generate the ToolboxSpaceType from the ProxyProperties array of strings. Is there a way to do that in TypeScript?

btelles
  • 5,390
  • 7
  • 46
  • 78
  • My answer [here](https://stackoverflow.com/a/45486495/2887218) is relevant; I'll flesh it out in an answer to this question. – jcalz Sep 20 '17 at 15:23

1 Answers1

1

Note: the code as presented in your post has problems and does not compile as written. The following answer only concerns the first two lines involving the ToolboxSpaceType type and the ProxyProperties array, since that's what you are asking about.


You can do it. It's best to add a helper function so your array will not be inferred as just string[]. The following function forces the array element type to be inferred as a union of string literals:

function literalArray<K extends string>(args: K[]): K[] {
  return args;
}

Now ProxyProperties is inferred as ('screw'|'hammer'|'screwdriver')[]:

const ProxyProperties = literalArray(['screw', 'hammer', 'screwdriver']);  

and you can compute the union by extracting its element type:

type ToolboxSpaceType = typeof ProxyProperties[number];

In an answer to another question I recommended a helper function (tuple() in tuple.ts) to infer tuple types, which might be even better for you, since ProxyProperties contains the literals exactly once in a known order. You'd use it like this:

const ProxyProperties = tuple('screw', 'hammer', 'screwdriver');  
//inferred as type ["screw", "hammer", "screwdriver"]

type ToolboxSpaceType = typeof ProxyProperties[number]; // still works

Hope that helps; good luck!

jcalz
  • 264,269
  • 27
  • 359
  • 360