reactjs - react typescript : Map over an array and insert values from an object with a shared key

标签 reactjs typescript

在常规的 javascript 中我可以做...

var array1 = ['one', 'two', 'three', 'four'];
var object = {
  one: 'apple',
  two: 'orange',
  three: 'peach',
  four: 'kiwi',
}

const map1 = array1.map(x => `${object[x]}`);

console.log(map1); // ["apple", "orange", "peach", "kiwi"]

但是在与 TypeScript react 时,我想在 JSX 中做类似的事情

<ul>
   { state.array1.map( (arrayItem:string, index:number) => (<li key={index} >{state.object[arrayItem]}</li>)) }
</ul>

类型脚本警告是:

Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ one: string; two: string; three: string; four: string;

这就是我声明对象的方式

const object: {
    one: string;
    two: string;
    three: string;
    four: string;
}

当我将鼠标悬停在它上面时,数组显示为 (属性) array1: 从不[]

当我保存 array1 时,它看起来像

 const [state, setState] = useState({ array1: []}); 

最佳答案

问题是 object 只有键 onetwothirdfour

您稍微误读了该警告。这里其实有两件事,第一件事是

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; }'.

这只是警告您,object[x] 不保证为您提供任何当前键 onetwo,或,因此无论它获取什么,都将被假定为any类型。这基本上涵盖了 object["Five"] 的情况 - 由于 TS 不知道这个属性的存在,它无法猜测它的类型 - 它可能是一个数字,或者一个字符串,或简单地未定义

No index signature with a parameter of type 'string' was found on type '{ one: string; two: string; three: string; four: string; }'.

这就是阻止你的原因。同样,TS 只知道属性 onetwothirdfour,但它不知道你的数组只包含那些。当您没有明确说明数组包含什么内容时,它会尝试推断 the best common type在本例中是字符串。并且由于字符串不能保证是 onetwothirdfour 中的任何一个(例如,可能是五个),那么 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);

Check on the TypeScript Playground

此外,如果您正式声明 object 的类型,则可以使用 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);

Check on the 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);

Check on the TypeScript Playground

你最好的选择是第二个和第三个。第一个实际上只是为了强调为什么它不起作用。 keyof 可与 'one' | 互换'两个' | '三'|在此代码中为 'four',但它的好处是,如果 object 的定义发生更改,则无需更新多个位置。

关于reactjs - react typescript : Map over an array and insert values from an object with a shared key,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58237601/

相关文章:

react-router - 为什么我的 catch-all 路由在我的 Switch 中不起作用?

javascript - Axios:对多个 axios 实例使用相同的拦截器

javascript - 状态更改后子组件不更新

javascript - 如何在 react 中显示加载程序。使用钩子(Hook)

javascript - 类型安全从函数对象调用某些函数

angular - 如果在特定文件夹中,由 angular CLI 生成的测试将失败

javascript - "location"是 react 中的保留字吗?如果是这样,它有什么作用?

typescript - 'XXX' 没有提供签名 'new (): XXX' 的匹配项

javascript - Typescript 组件运行正确,但表示存在错误,因为它无法识别那里的属性

RouteConfigLoadEnd-Handler 中的 Angular 访问 route._loadedConfig