如何修复 Element 隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型?

Posted

技术标签:

【中文标题】如何修复 Element 隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型?【英文标题】:how fix Element implicitly has an 'any' type because expression of type 'string' can't be used to index type? 【发布时间】:2021-07-01 01:20:51 【问题描述】:

为 React 项目尝试 TypeScript,但我遇到了这个错误。

TS7053:元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型“ paymentMethod: string;金额:字符串;收据代码:字符串;付款日期:字符串;支付源ID:字符串; '。在“ paymentMethod: string; 类型”上找不到带有“string”类型参数的索引签名金额:字符串;收据代码:字符串;付款日期:字符串;支付源ID:字符串; '

当我尝试 setInputs()

setInputs(inputs => (...inputs, [inputs.field[eventName]]: eventValue));

这是我的组件。

import React, useState from 'react';
import DatePicker from "jalali-react-datepicker";
import axios from "axios";
import PaymentFormClasses from './PaymentForm.module.css';
import PaymentCard from "../../Cards/PaymentCard/PaymentCard";
import Card from "../../Cards/Card";

interface PaymentForm 
    field: 
        paymentMethod: string,
        amount: string,
        receiptCode: string,
        paymentDate: string,
        paymentSourceID: string
    


const PaymentForm = () => 
    const [inputs, setInputs] = useState<PaymentForm>(
        field: 
            paymentMethod: '',
            amount: '',
            receiptCode: '',
            paymentDate: '',
            paymentSourceID: 'paymentSourceID'
        
    );

    const changedHandler = (e: React.ChangeEvent<htmlInputElement> | React.ChangeEvent<HTMLSelectElement>) => 
        console.log(typeof e.target.name);
        const eventName = e.target.name;
        const eventValue = e.target.value;

        setInputs(inputs => (...inputs, [inputs.field[eventName]]: eventValue));
        console.log(e.target.value);
    
   

    return (
        <>

        </>
    );
;

export default PaymentForm;

【问题讨论】:

这是一个很常见的问题。我确信这可以作为副本关闭。做const eventName = e.target.name as keyof PaymentForm['field']; 我真的对你的语法 ...inputs, [inputs.field[eventName]]: eventValue 感到困惑,我相信它应该类似于 ...inputs, inputs.field[eventName]: eventValue @pavankumar inputs.field[eventName]: eventValue 语法无效。应该是 field: ...inputs.field, [eventName]: eventValue 【参考方案1】:

您需要断言e.target.name(始终只是string)实际上是inputs.field 的有效键。

const eventName = e.target.name as keyof PaymentForm['field'];

但是您的更新语法不正确。您正在设置输入的***属性,并且您使用 inputs.field[eventName] 作为属性名称。

您可以进行嵌套更新:

setInputs(inputs => ( 
  ...inputs, 
  field:  
    ...inputs.field, 
    [eventName]: eventValue 
  
));

但是为什么我们需要这个field 属性呢?它是inputs 中唯一的属性,所以我们为什么不让它成为整个状态。

interface Fields 
  paymentMethod: string;
  amount: string;
  receiptCode: string;
  paymentDate: string;
  paymentSourceID: string;


const PaymentForm = () => 
  const [fields, setFields] = useState<Fields>(
    paymentMethod: "",
    amount: "",
    receiptCode: "",
    paymentDate: "",
    paymentSourceID: "paymentSourceID"
  );

  const changedHandler = (
    e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
  ) => 
    setFields((fields) => (
      ...fields,
      [e.target.name as keyof Fields]: e.target.value
    ));
  ;

  return <></>;
;

【讨论】:

【参考方案2】:

您的 eventName 可以是字段键的联合。试试这个。

type EventName = 'paymentMethod' | 'amount' | 'recieptCode' ...etc;
const eventName = e.target.name as EventName; // OR

const eventName = e.target.name as keyof PaymentForm['field'];

【讨论】:

以上是关于如何修复 Element 隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复绑定元素'children'隐式具有'any' type.ts(7031)?

编译打字稿时如何防止错误“对象类型的索引签名隐式具有'任何'类型”?

src/app/app.component.ts(391,9) 中的错误:错误 TS7017:元素 > 隐式具有“任何”类型,因为类型“Foo”没有索引签名

参数隐式具有“任何”类型

如何使用命名数组的接口:元素隐式具有“任何”类型,因为索引表达式不是“数字”类型

元素隐式具有“任何”类型,因为类型的表达式