The problem is that object only has keys one, two, three and four
You are slightly misreading the warning. There are actually two things here, the first one is
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ one: string; two: string; three: string; four: string; }'.
Which simply warns you that object[x] is not guaranteed to give you any of its current keys one, two, three, or four, so whatever it fetches will be assumed to be any type. This basically covers the situation object["five"] - since TS does not know of the existence of this property, it cannot guess what the type of it would be - it might be a number, or a string, or simply undefined.
No index signature with a parameter of type 'string' was found on type '{ one: string; two: string; three: string; four: string; }'.
This is what is stopping you. Again, TS only knows of the properties one, two, three, and four, however it cannot know that your array contains only those. When you haven't explicitly said what the array contains, it would try to infer the best common type which in this case is string. And since a string is not guaranteed to be any of one, two, three, and four (e.g., it might be five), then TS cannot guarantee what you do is safe.
You can explicitly say that your array only holds variables that are viable keys:
var array1: Array<'one' | 'two' | 'three'| 'four'> = ['one', 'two', 'three', 'four'];
var object = {
one: 'apple',
two: 'orange',
three: 'peach',
four: 'kiwi',
}
const map1 = array1.map(x => `${object[x]}`);
console.log(map1);
Check on the TypeScript Playground
Furthermore, if you formally declare what object's type would be, you can use keyof instead of manually listing all keys:
interface MyObject {
one: string;
two: string;
three: string;
four: string;
}
var array1: Array<keyof MyObject> = ['one', 'two', 'three', 'four'];
var object: MyObject = {
one: 'apple',
two: 'orange',
three: 'peach',
four: 'kiwi',
}
const map1 = array1.map(x => `${object[x]}`);
console.log(map1);
Check on the TypeScript Playground
Although you could be a bit more informal and not declare a specific type for object. This would lead to the following code which will check what the inferred type of object is and then make an array of all keys:
var array1: Array<keyof typeof object> = ['one', 'two', 'three', 'four'];
var object = {
one: 'apple',
two: 'orange',
three: 'peach',
four: 'kiwi',
}
const map1 = array1.map(x => `${object[x]}`);
console.log(map1);
Check on the TypeScript Playground
Your best options are the second and third. The first one is really just there to highlight why it doesn't work. keyof is interchangeable with 'one' | 'two' | 'three'| 'four' in this code but it has the benefit of not needing to update multiple places if object's definition changes.
array1andobject?