Suppose:
export enum EEnv { devint, qa1 };
export type TEnv = keyof typeof EEnv;
export const env:Record<TEnv, {something:number}> = {
devint: {
something: 1,
},
qa1: {
something: 1,
},
}
Then I want to create dynamic object based on env object, like this:
export const SAVE_TOKEN: Record<TEnv, string> = {
devint: "SAVE_TOKEN/devint", // based on "env" key
qa1: "SAVE_TOKEN/qa1", // based on "env" key
}
Is there any way to create type of string to be "SAVE_TOKEN/"+TEnv rather that just string.
Update for those who still find their way here: this will be added in 4.1, see TypeScript#40336.
export type SaveTokenNamespace<K extends string> = { [T in K]: `SAVE_TOKEN/${T}` };
export function makeNamespace<K extends TEnv>(env: Record<K, unknown>): SaveTokenNamespace<K> {
return Object.keys(env).reduce((ns, k) => ({ ...ns, [k]: `SAVE_TOKEN/${k}` }), {} as SaveTokenNamespace<K>);
}
console.log(makeNamespace(env));
const envNamespace = makeNamespace(env);
const test1: 'SAVE_TOKEN/qa1' = envNamespace.qa1; // Ok!
const test2: 'SAVE_TOKEN/notqa1' = envNamespace.qa1; // Error: Type '"SAVE_TOKEN/qa1"' is not assignable to type '"SAVE_TOKEN/notqa1"'.
Try it in the TypeScript playground
There are some popular open proposals/requests including Regex-validated string type: TypeScript#6579 and TypeScript#12754 with a comment about this exact use case, but as of 3.5.1 the answer is no.
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