【问题标题】:Type 'undefined' cannot be used as an index type类型 \'undefined\' 不能用作索引类型
【发布时间】:2023-01-31 05:15:10
【问题描述】:

我正在尝试将一个函数从 Javascript 转换为 Typescript,但我一直遇到以下错误:

类型“undefined”不能用作索引类型

我知道 undefined 不能用作索引,但我已经尝试对索引类型进行空检查以及条件渲染,但似乎没有任何效果。

这是我的代码:

我用于函数的值的 useState 挂钩

const [newUser, setNewUser] = useState({
    firstName: "",
    lastName: "",
    companyName: "",
    email: "",
    password: "",
    id: ""
  });

const [errorMessage, setErrorMessage] = useState("");

该函数本质上是采用 newUser 的初始值,制作该对象的副本,然后调用 setNewUser 将用户输入的字段填充到 newUser 复制的对象中。

const setValues = (propName?: number, value?: any) => {
        const cloneUser = { ...newUser };
        cloneUser[propName] = value;
        setNewUser({ ... cloneUser });
        setErrorMessage("");
  }

我的主要问题是cloneUser[propName]不能未定义并用作索引,我不确定如何解决这个问题。

【问题讨论】:

  • 我猜是因为 propName 在你的 setValues 函数中是可选的。
  • @DavidScholz 一旦我删除了?从 propName 我收到以下错误:Element implicitly has an 'any' type because expression of type 'number' can't be used to index type '{ firstName: string; lastName: string; companyName: string; email: string; password: string; id: string; }'.

标签: typescript react-native object indexing undefined


【解决方案1】:

回答

将 setValues 函数重新定义为:

const setValue = (propName: keyof typeof newUser, value: string) => {
  // your update code here
}

更改参数类型以匹配您的状态类型,推断为:

{
  firstName: string;
  lastName: string;
  companyName: string;
  email: string;
  password: string;
  id: string;
}

或者

指定状态类型:

type User = Readonly<{
  firstName: string;
  lastName: string;
  companyName: string;
  email: string;
  password: string;
  id: string;
}>;

// in the component
const [newUser, setNewUser] = useState<User>({
  // initialize here
});

并将函数定义为:

const setValue = (propName: keyof User, value: string) => { ... }

解释

propName 不能是 number | undefined,因为它用于使用 string 键(您的州)索引对象。它必须是string。

您面临的问题是由定义为propName?: number 的propName 参数引起的。

这个(propName?: number, value?: any) =&gt; { ... } 等同于(propName: number | undefined, value: any | undefined) =&gt; { ... }。这意味着在您的 setValues 函数中 propName 可能未定义,这被正确检测为错误,因为 undefined 值不能用于索引对象。

建议

我还建议将函数的名称更改为setValue,因为您当时只设置一个给定的属性。

此外,您正在设置字符串值,因此该值也可以是非可选的并键入为 string。

【讨论】:

  • 我刚刚将函数重新定义为 const setValue = (propName: string, value: string) =&gt; { 但现在我收到此错误 => Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ firstName: string; lastName: string; companyName: string; email: string; password: string; id: string; }'. No index signature with a parameter of type 'string' was found on type '{ firstName: string; lastName: string; companyName: string; email: string; password: string; id: string; }'.
  • 嘿@melly18,感谢您指出这一点!我更新了我的答案,因为我忽略了这一点。问题是您的状态的推断类型不包含 string 索引签名。 TypeScript 通过禁止传递与状态属性不匹配的任意 propName 来指出这一点。解决方案是使用 keyof 运算符并将其指向 typeof newUser 或为您的州单独定义的类型,例如User
  • 这解决了我的问题!谢谢你。在概念上使用更有意义:const setValue = (propName: keyof typeof newUser, value: string) =&gt; {
【解决方案2】:

看起来您正在尝试使用数字键和任何值任意向该对象添加键值对。您需要通过定义类型来告诉打字稿这是允许的,并将其传递给useState 的通用参数。

演示:https://stackblitz.com/edit/react-ts-mpdukw?file=App.tsx

type User = {
  firstName: string;
  lastName: string;
  companyName: string;
  email: string;
  password: string;
  id: string;
  [key: number]: any; // This lets you add a numeric key with any value
};
  // generic parameter defines the type of `newUser`
  const [newUser, setNewUser] = useState<User>({
    firstName: '',
    lastName: '',
    companyName: '',
    email: '',
    password: '',
    id: '',
  });

然后,允许未定义的键没有意义,因此将该属性设为强制性:

  const setValues = (propName: number, value?: any) => {
    setNewUser({ ...newUser, [propName]: value });
    setErrorMessage('');
  };

根据用例,您可能希望允许使用未定义的键,并在这种情况下跳过步骤。

  const setValues = (propName?: number, value?: any) => {
    if (propName) setNewUser({ ...newUser, [propName]: value });
    setErrorMessage('');
  };

【讨论】:

    猜你喜欢
    • 2023-01-20
    • 2018-02-13
    • 1970-01-01
    • 2021-12-16
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多