Something close to what you want is possible. Firstly we need to improve on the type of the array. By default the keys array will be of type string[] this does not help us as we need the string literal types for the string values. This helper function will help with that:
function arrayHelper<T extends string>(a: T[]) : T[] {
return a;
}
var keys = arrayHelper(["A1", "B1", "C1"]); // The type of keys will be ("A1" | "B1" | "C1")[]
Now that we have the string literal types, we can easily define a type based off them :
var object = (<T extends string>(o: T[]) =>
{
const obj: { readonly [P in T]: P} = <any>{}
keys.forEach((key) => {
obj[key] = key
});
return obj;
})(keys);
The type of object will be
var object: {
readonly A1: "A1";
readonly B1: "B1";
readonly C1: "C1";
}
An object that has the original values as keys and the value of the same type as the string literal.
The key is the full value not a substring (it is not possible to perform complex mutations on property names), but this might be something you can live with.
{ [key: string]: string }.type objType = { A1: 'A1', A2: 'A2' }?{ [key: string]: string }, you wouldn't be able to have type completion.fs.readFileSyncwith those strings), because Jest couldn't handleImageRequireSourceproperly. I'm creating an object so that files that import assets could simply import from this sort of central asset reference so they can do<Image source={asset.something} />, that's why I can't have the generic{ [key: string]: string }.