问题是object
只有键one
, two
,three
和four
您稍微误读了警告。这里实际上有两件事,第一件事是
元素隐式具有 'any' 类型,因为类型 'string' 的表达式不能用于索引类型 '{ one: string; 二:字符串;三:字符串;四:字符串;}'。
这只是警告你object[x]
不能保证给你任何当前的键one
, two
, three
, or four
,所以无论它获取什么都将被假定为any
类型。这基本上涵盖了这种情况object["five"]
——因为 TS 不知道这个属性的存在,它无法猜测它的类型——它可能是一个数字,或者一个字符串,或者只是undefined
.
在类型 '{ one: string; 二:字符串;三:字符串;四:字符串;}'。
这就是阻止你的原因。同样,TS 只知道属性one
、two
、three
和four
,但是它无法知道您的数组仅包含这些属性。当您没有明确说明数组包含什么时,它会尝试推断最常见的类型,在这种情况下是string
. 而且,由于一个字符串不保证任何的one
,two
,three
,和four
(例如,它可能是five
),然后TS不能保证你做什么是安全的。
您可以明确地说您的数组仅包含作为可行键的变量:
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);
检查 TypeScript Playground
此外,如果您正式声明object
's 类型是什么,您可以使用keyof
而不是手动列出所有键:
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);
检查 TypeScript Playground
尽管您可能会更非正式一些并且不为object
. 这将导致以下代码,它将检查推断的类型object
是什么,然后创建一个包含所有键的数组:
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);
检查 TypeScript Playground
您最好的选择是第二个和第三个。第一个实际上只是为了强调为什么它不起作用。keyof
与'one' | 'two' | 'three'| 'four'
此代码中的可互换,但它的好处是如果object
的定义发生更改,则无需更新多个位置。