網站搜尋

reactjs - 重複的字串索引簽名.ts(2374)


以下是我想在 TypeScript 中使用索引簽名創建的類型。

export interface LoginState {
    account: {
              [userName: string]: string;
              [password: string]: string;
           };
}

但是,我遇到了標題中所述的錯誤。

該工具對密碼欄位提出警告/標示出來。

我找到了以下答案:在 Reactjs 與 Typescript 中出現『Duplicate string index signature』(重複的字串索引簽名)錯誤。但這對我的問題沒有幫助。

有人可以指出我在這裡犯的錯誤嗎?

如需進一步說明,請隨時提出問題。

乾杯,RSF

附註:添加完整的組件實現:

import * as React from "react";
import { User } from "./../interfaces/User";
import { SecurityService } from "./../services/SecurityService";

export interface LoginProps {
  onLogged: (user: User) => void;
}

export interface LoginState {
  currentUser: User | null;
  account: {
         [userName: string]: string;
         [password: string]: string;
  };
}

export class Login extends React.Component<LoginProps, LoginState> {

   constructor(props: LoginProps) {
          super(props);

          this.state = {
          currentUser: null,
               account: {
               userName: "",
               password: ""
           }
        };
   }

  handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
     e.preventDefault();
  };

  handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      let account = { ...this.state.account };
      account[e.currentTarget.name] = e.currentTarget.value;
 };

 render() {
  return (
  <div>
    <h1>Login</h1>
    <form onSubmit={this.handleSubmit}>
      <div className="form-group">
        <label htmlFor="userName">Username</label>
        <input
          autoFocus
          onChange={this.handleChange}
          name="userName"
          id="userName"
          type="text"
          className="form-control"
        />
      </div>
      <div className="form-group">
        <label htmlFor="password">Password</label>
        <input
          onChange={this.handleChange}
          name="password"
          id="password"
          type="text"
          className="form-control"
        />
      </div>
      <button className="btn btn-primary">Login</button>
    </form>
  </div>
   );
  }
 }

答案#1

來自 TypeScript 手冊

與我們可以使用介面來描述函數類型類似,我們也可以描述可以像 a[10] 或 ageMap["daniel"] 這樣「索引」的類型。可索引類型具有索引簽名,該簽名描述了我們可以用來索引對象的類型,以及索引時對應的返回類型。

當你使用 index types 時,你只是告訴 TypeScript 當一個自訂類型被索引時,你會得到什麼返回類型。

所以你只需要告訴 Typescript,當你用字串類型索引 account 時,會返回字串類型。就是這樣。

export interface LoginState {
  currentUser: User | null;
  account: {
      // Tells Typescript that a string index on account would return a string
      [k: string]: string;

      username: string;
      password: string;
      address: string;
      anotherField: string;
  };
}

通過這樣定義它:

[userName: string]: string;
[password: string]: string;    // This is a duplicate string index

你正在做這個:

[k1: string]: string;
[k2: string]: string;    // This is a duplicate string index

這是錯的,因為你告訴 TypeScript 兩次相同的事情:如果你用字串索引 account,你會得到字串。如果你用字串索引 account,你會得到字串。

稍後,如果你想在 account 中新增名為 id 和 age 的 number 類型欄位,你的定義會如下所示:

export interface LoginState {
  currentUser: User | null;
  account: {
      // Tells Typescript that a string index on account would return a string OR a number
      [k: string]: string | number;

      username: string;
      password: string;
      address: string;
      anotherField: string;
      id: number;
      age: number;
  };
}