简体   繁体   English

无法使用打字稿向对象文字添加新属性

[英]Unable to add new properties to an object literal using typescript

There are questions on stackoverflow for the same but their accepted answers are not working for me as none of them is using an object literal. 对于stackoverflow也有同样的问题,但是他们接受的答案对我不起作用,因为它们都没有使用对象文字。 Without wasting your time. 不浪费您的时间。 Here's my code. 这是我的代码。

contribute.component.ts ( contribute is just a name of my component i created with ng generate component contribute ). commit.component.tscontribute只是我用ng generate component contribute创建的我的组件的名称)。

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-contribute',
  templateUrl: './contribute.component.html',
  styleUrls: ['./contribute.component.css']
})
export class ContributeComponent implements OnInit {
  makeNewPost={}; //THI IS MY EMPTY OBJECT TO WHICH I WANT TO ADD PROPERTIES LATER IN THIS CODE

  constructor(private _auth: AuthService) { }

  ngOnInit() {
      //SOME CODE
  }

  //THIS FUNCTION WILL BE CALLED ON CLICK EVENT FROM `contribute.component.html`
  onSubmit() {
    var email = (<HTMLInputElement>document.getElementById("email")).value;
    var password = (<HTMLInputElement>document.getElementById("password")).value;

    console.log(email); //SEEMS GOOD ON CONSOLE
    console.log(password); //SEEMS GOOD ON CONSOLE

    //THESE TWO PROPERTIES I WANT TO ADD
    this.makeNewPost.email=email;
    this.makeNewPost.password=password;

    this._auth.registerNewt(this.makeNewPost)
    .subscribe (
      res => console.log(res),
      err => console.log(err)
    );
  }
}

But my knowledge says that objects are mutable in ts . 但据我所知,对象在ts是可变的。 Then why I am getting this error. 那为什么我得到这个错误。

error TS2339: Property 'email' does not exist on type '{}'. 错误TS2339:类型“ {}”上不存在属性“电子邮件”。 error TS2339: Property 'password' does not exist on type '{}'. 错误TS2339:类型“ {}”上不存在属性“密码”。

Please tell if I am wrong about objects in typescript. 请告诉我,如果我错了有关打字稿对象。

I also tried declaring my object as: 我还尝试将我的对象声明为:

makeNewPost= {
  email: string;
  password: string;
}

PS: It is an Angular 8 project PS:这是一个Angular 8项目

Most of the point of TypeScript is that it provides static typing for variables. TypeScript的主要意义在于它为变量提供了静态类型 When you do 当你做

 makeNewPost={};

...since you haven't specified a type for makeNewPost , TypeScript infers it from {} , and makes it a type with no properties. ...由于您尚未为makeNewPost指定类型, makeNewPost TypeScript从{}推断出它的类型,并使它成为没有属性的类型。 Later, of course, you're trying to add properties, but while that's fine in JavaScript, with TypeScript's static typing, it's a problem. 当然,稍后,您尝试添加属性,但是在JavaScript中可以正常使用TypeScript的静态类型,但这是一个问题。

The solution is to include the properties up front, and then just change their values: 解决方案是先包含属性,然后更改它们的值:

 makeNewPost = {
    email: "",
    password: ""
 };

Now, TypeScript will infer the type as an object with email and password properties, both strings, and you can assign to them later. 现在,TypeScript会将类型推断为具有emailpassword属性(两个字符串)的对象,您以后可以分配给它们。


You don't have to add the properties initially, though that's probably the cleanest solution. 您不必一开始就添加属性,尽管这可能是最干净的解决方案。 You could define a type for makeNewPost and make the properties optional (the ? in the property definition): 您可以为makeNewPost定义类型,并使属性为可选 (属性定义中的? ):

interface NewPost {
    email?: string;
    password?: string;
}

Then use that type: 然后使用该类型:

makeNewPost: NewPost = {};

Later, you'll be able to assign the properties because they're allowed to exist. 稍后,您将能够分配属性,因为它们被允许存在。

I wouldn't do that, though, because when you need to actually make a new post, those properties aren't optional. 不过,我不会这样做,因为当您实际需要撰写新文章时,这些​​属性不是可选的。

A third approach would be to define a type without optional properties: 第三种方法是定义没有可选属性的类型:

interface NewPost {
    email: string;
    password: string;
}

...and declare makeNewPost to be Partial<NewPost> : ...并声明makeNewPostPartial<NewPost>

makeNewPost: Partial<NewPost> = {};

You'd have this._auth.registerNewt accept NewPost , not Partial<NewPost> , but use a type assertion after you've filled it in to say (in essence) "I've filled it in now:" 您将具有this._auth.registerNewt接受NewPost ,而不是Partial<NewPost> ,但是在填写它之后使用类型断言来说(本质上)“我现在已经将其填写:”

this.makeNewPost.email = email;
this.makeNewPost.password = password;

this._auth.registerNewt(this.makeNewPost as NewPost)
// ...

You're using TypeScript. 您正在使用TypeScript。 You can create a type for 'Post': 您可以为“发布”创建类型:

export interface Post{
  email : String
  password : String
}

Then declare makeNewPost to be of type Post , and immediately initiate it with your values: 然后将makeNewPost声明为Post类型,并立即使用您的值将其初始化:

let makeNewPost: Post = {
  email : email,
  password : password
}

If you don't know the properties of the object beforehand, you could make a custom type like: 如果您事先不知道对象的属性,则可以进行如下自定义类型:

type NewObject = {[key: string]: any};
let newObject: NewObject = {};
newObject.property = 'value';

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

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