简体   繁体   English

我无法访问 HTML 模板中对象的属性 - Angular

[英]I can't access properties of objects in HTML template - Angular

I have two objects that handle errors in the form:我有两个处理表单错误的对象:

formErrors =
  {
    'firstname': '',
    'lastname': '',
    'telnum': '',
    'email': ''
  }

ValidationMessages = {
  'firstname':{
    'required': 'First name is required.',
    'minlength': 'First name must be at least two characters long.',
    'maxlength': 'First name must be at least twenty-five characters long.'
  },
  'lastname':{
    'required': 'Last name is required.',
    'minlength': 'Last name must be at least two characters long.',
    'maxlength': 'Last name must be at least twenty-five characters long.'
  },
  'telnum':{
    'required': 'Tel. number  is required.',
    'pattern': 'Tel. number must contain only numbers.'
  },
  'email':{
    'required': 'Email is required.',
    'email': 'Email not in valid format.'
  }
}

Here is a validator using these objects:这是一个使用这些对象的验证器:

onValueChanged(data?: any){
  if (!this.feedbackForm) {return;}
  const form = this.feedbackForm;
  for (const field in this.formErrors){
    if (this.formErrors.hasOwnProperty(field)) {
      //clear previous error message (if any)
      this.formErrors[field] = ''
      const control = form.get(field);
      if (control && control.dirty && !control.valid){
        const messages = this.ValidationMessages[field];
        for (const key in control.errors){
          if (control.errors?.hasOwnProperty(key)){
            this.formErrors[field] += messages[key] + ' ';
          }
        }
      }
    }
  }
}

I've tried to get properties from my array object but I get the error: TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ firstname: string; lastname: string; telnum: string; email: string; }'.我试图从数组 object 中获取属性,但出现错误: TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ firstname: string; lastname: string; telnum: string; email: string; }'. TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ firstname: string; lastname: string; telnum: string; email: string; }'. I need to type any ok我需要输入任何 ok

I've fixed this by typing my array with any , but I've got new errors like I can't get any properties from here我已经通过在我的数组中输入any来解决这个问题,但是我遇到了新的错误,比如我无法从这里获取任何属性

Does someone know how to solve it?有人知道如何解决吗?

When you assign an object to a variable, Typescript types it on-the-fly.当您将 object 分配给变量时,Typescript 会即时键入它。 Taking your formErrors object for example, what you wrote is equivalent for Typescript to:以你的formErrors object 为例,你写的 Typescript 等同于:

interface FormErrors {
    firstname: string;
    lastname: string;
    telnum: string;
    email: string;
}

const formErrors: FormErrors  = {
    firstname: '',
    lastname: '',
    telnum: '',
    email: ''
}

As you can see, if you used that kind of typing for your object you wouldn't expect to access any other property than the 4 you declared in the FormErrors interface.如您所见,如果您对 object 使用这种类型的类型,您将不会期望访问除您在FormErrors接口中声明的 4 之外的任何其他属性。 And that's what Typescript is telling you.这就是 Typescript 告诉你的。

When you try and access your object's property through a variable ( formErrors[field] ), this variable could contain any possible string and not just the 4 keys allowed by your object's type.当您尝试通过变量 ( formErrors[field] ) 访问对象的属性时,该变量可以包含任何可能的字符串,而不仅仅是对象类型允许的 4 个键。 Typescript does not care that you're looping over the keys, that's only known to you at this point. Typescript 不在乎您是否在键上循环,此时只有您知道。

You have two options when facing this error:遇到此错误时,您有两种选择:

  1. Make your type/object indexable使您的类型/对象可索引
  2. Use the keyof operator to tell Typescript that your variable is a valid key使用keyof运算符告诉 Typescript 你的变量是一个有效的键

Indexable types可索引类型

You make a type indexable by saying "this object can contain any key" making it possible to use a string variable to access an object's property.您可以通过说“this object can contain any key”使类型可索引,从而可以使用字符串变量访问对象的属性。

Applied to the FormErrors example:应用于FormErrors示例:

interface FormErrors {
    [key: string]: string;
    firstname: string;
    lastname: string;
    telnum: string;
    email: string;
}

Notice the line I've added before your properties: it's the index signature saying that FormErrors can contain a bunch of keys associated with string values.请注意我在您的属性之前添加的行:它是索引签名,表示FormErrors可以包含一堆与字符串值关联的键。 You could now write formErrors['banana'] and Typescript wouldn't say anything.你现在可以写formErrors['banana']和 Typescript 什么也不会说。

Note that this signature can be used on its own, I've kept the properties because it lets you write things like formErrors.lastname (instead of formErrors['lastname'] ) and get autocompletion.请注意,此签名可以单独使用,我保留了属性,因为它允许您编写类似formErrors.lastname (而不是formErrors['lastname'] )的东西并获得自动完成功能。

Here is a random article that will explain you more about indexable types. 是一篇随机文章,将向您解释有关可索引类型的更多信息。

keyof operator keyof员键

A better way to solve this in such cases where you know the exhaustive list of properties is to use the keyof operator to tell Typescript that your string variable can only contain a key that belongs to your type.在您知道详尽的属性列表的情况下,解决此问题的更好方法是使用keyof运算符告诉 Typescript 您的字符串变量只能包含属于您的类型的键。

A valid loop for the FormErrors interface (without index signature) would be: FormErrors接口(没有索引签名)的有效循环是:

Object.keys(formErrors).forEach((key: keyof FormErrors) = {
    formErrors[key] = 'data';
});

Here is Typescript's documentation about keyof , and here is another random article to know more about it. Here is Typescript's documentation about keyof是另一篇随机文章以了解更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM