I have an array of static strings that I want to create an interface off of. The best way to explain this is to show an example of psedo-interfaces:
const types = ["error", "warning", "success"];
interface Modal {
type: keyof types;
}
I need to use the types, in order, in my actual js so I was hoping there was a way to express this in the interface so I don't have to duplicate the values in the array and the interface. Is this possible?
You can get this, but the problem is that types is widened to string[], which loses the information about which specific strings are in the array, and in which order.
If all you want is the particular strings and don't care about the order, you can make a helper function which uses a trick to get types to be inferred as a narrower type (you can read this issue for more info about how to prevent widening):
const narrowArray = <K extends string>(...arr: K[]) => arr;
And use it:
const types = narrowArray("error", "warning", "success");
Now types is inferred to be Array<"error"|"warning"|"success">. If you want Modal['types'] to be one of those strings (not clear from your post... keyof certainly won't do it), then you can do this:
interface Modal {
type: (typeof types)[number]; // "error" | "warning" | "success"
}
That should work for you.
Also relevant: starting in TypeScript 3.0 there will be a way to infer tuple types which will let you keep track of the ordering of types as well. It will be like this:
// only works in TS3.0 and up
const narrowTuple = <K extends string[]>(...arr: K) => arr;
const types = narrowTuple("error", "warning", "success");
// types is inferred as type ["error", "warning", "success"]
Now types is inferred as the triple ["error", "warning", "success"], and so at compile time TypeScript will know that, for example, types[1] is specifically "warning". (You don't need to keep track of ordering for the Modal['type'] definition above, unless I'm not understanding what you want Modal['type'] to be.)
Hope that helps. Good luck!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With