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!