Reputation: 788
I have a function which converts array values into keys in a object:
function x(keys: string[]) {
const obj: any = {};
keys.forEach(v => {
obj[v] = 'somevalue...';
});
return obj;
}
const result = x(['a', 'b', 'c']);
console.log(result); // {a: "somevalue...", b: "somevalue...", c: "somevalue..."}
Is it possible to tell TypeScript that return value of this function will be {<values of array>: string}
?
Upvotes: 4
Views: 103
Reputation: 66480
Since typescript's typings are only available at compile-time, there is no way for it to infer that information at runtime, esp. if the array is dynamically created. (If your keys are constant, have a look at Titian's solution.)
For typescript, your array is an array of strings.
You can type your returned object of the x
function with the index signature to avoid the any type hint:
const obj: {[key: string]: string} = {};
Yet keep in mind that it won't check for the existence of a key.
So the compiler will think that
const exists = obj["a"];
const doesntExists = obj["junk"];
are okay. You still have to check for undefined values.
Upvotes: 2
Reputation: 249506
If your function is mostly called with constants, it makes sense to use a generic type parameter to capture the actual strings passed into the function in a generic type parameter. You can the use this type parameter with record to get a strongly typed object that will have the keys you specified.
function x<K extends string>(keys: readonly K[]) {
const obj = {} as Record<K, string>;
keys.forEach(v => {
obj[v] = 'somevalue...';
});
return obj;
}
const result = x(['a', 'b', 'c']); // Record<"a" | "b" | "c", string>, same as {a: string, b: string, c: string}
result.a;
const keys = ['a', 'b', 'c'] as const
const result2 = x(keys);// Record<"a" | "b" | "c", string>
const skeys = ['a', 'b', 'c']// string[]
const result3 = x(keys);// Record<string, string>, same as { [n: string]: string }
If the function is called with an array that contains string
you will get a plain index signature so you will not be worse off with this version.
Upvotes: 2