1

In python I usually just do something like this:

## single person
class Person:
    def __init__(self, first_name, last_name, age):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age

## empty when instantiated
class People:
    def __init_(self):
        self._people = {}

    def update(self, Person):
        self._people[Person.first_name] = Person

    def update2(self, person):
        self.update(Person(**person))


people = People()
people.update2({'first_name': 'Mike', 'last_name': 'Smith', 'age':7})

My goal is to implement that exact behavior in typescript. Here is what I have so far.

class  Person {
    constructor(first_name, last_name, age){}
}

class People{
    public _people;

    constructor(){
        //not sure if there is a cleaner way to add _people to new instances
        this._people = {}
    }

    update(Person){
        this._people[Person.first_name] = Person
    }
    update2(my_object){
        //Person(my_object) should return an instance of the Person class
        this.update(Person(my_object))
    }
}

var people = new People()
people.update2({first_name:'Bob', last_name:'Smith', age:7})

Explanation for non-python people.

The goal is to create a People class that can hold instances of the Person class. I want to pass an object into update2, and use the keys/values of that object to create instances of the Person class.

Please let me know if anything isn't clear.

user2263572
  • 5,435
  • 5
  • 35
  • 57

1 Answers1

1

Here is how I would write it in TypeScript. I have changed the case of some variables to make it more 'TypeScript-like'.

I have also added types where they were missing.

class Person {
    // Public getters/setters
    public firstName: string;
    public lastName: string;
    public age: number;

    constructor({firstName, lastName, age}: { firstName?: string, lastName?: string, age?: number }) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.age = age;
    }
}

class People {
    // Declare _people as an object with keys as strings and values as Person instances
    public _people: {[key: string]: Person};

    update(person: Person) {
        this._people[person.firstName] = person;
    }

    // Add a signature to obj to make it clear what you are expecting
    update2(obj: {firstName: string, lastName: string, age: number}) {
        this.update(new Person(obj));
    }
}

var people = new People()
people.update2({ firstName: 'Bob', lastName: 'Smith', age: 7 });

console.log(people._people);

Or if Person is a simple data object, I suggest you don't use a class but a simple JS Object with an interface:

interface Person {
    firstName?: string,
    lastName?: string,
    age?: number
}

const person1: Person = { firstName: 'Jane', lastName: 'Doe', age: 25};
klugjo
  • 19,422
  • 8
  • 57
  • 75
  • Few questions. In Person, isn't the code in the constructor done automatically without the need to write it out? In People, will _people be shared across all people instances? I want each new instance of People to have it's own _people object. Also, in many cases my classes have LOTS of attributes. Is there anyway to avoid writing obj.firstName, obj.lastName...etc within update2? Thanks, this may be exactly what I'm looking for. – user2263572 Apr 27 '18 at 01:40
  • Edited my answer. No you need to set the properties in the constructor as far as I know. `_people` will not be shared across instances (just like any OO language that I know). To avoid writing obj.firstName and so on, you can use object destructuring as I shown now. If Person is a simple data object, just use an object directly with an interface instead of a class. – klugjo Apr 27 '18 at 01:58
  • 1
    https://stackoverflow.com/questions/33217963/combining-the-parameter-properties-shorthand-with-destructuring-in-typescript (with destructuring it looks like you need to set them, otherwise no). In python, class variables are shared amongst instances. Person will have a number of methods, in the actual implementation. Thanks for the snippet, should get me to where I need to be. – user2263572 Apr 27 '18 at 02:21