简体   繁体   中英

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. 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 ).

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 . Then why I am getting this error.

error TS2339: Property 'email' does not exist on type '{}'. error TS2339: Property 'password' does not exist on type '{}'.

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

Most of the point of TypeScript is that it provides static typing for variables. 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. 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.

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.


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):

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> :

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.makeNewPost.email = email;
this.makeNewPost.password = password;

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

You're using 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:

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';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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