I'm bit confused in how to use OOP in typescript.
I'm used to do it with PHP.
1 - Can I use a class as a type without having to fill all attributes values?
2 - Do I really need to create an interface to create class attributes and use it as type in some function?
For example, this is my class:
class User {
protected id: number;
protected name: string;
protected age?: Date;
constructor(id: number, name: string, age: Date) {
this.id = id;
this.name = name;
this.age = age;
}
getId() return this.id;
getName() return this.name;
setName(value: string) this.name = value;
getAge() return this.age;
setAge(value: Date) this.age = value;
And this is my service function:
const test = () => {
const user = new User({id: 1, name: 'Rick' });
}
I tried many ways and all returned some error, this is the main one.
Type '{ id: string; name: string; }' is missing the following properties from type 'User': getId, getName, setName
I know I can do this with interface, but I'm looking for a way to do this without interfaces, if it's possible.
CodePudding user response:
How about this...
class User {
protected id: number;
protected name: string;
protected age?: Date;
constructor({id, name, age }: { id: number, name: string, age?: Date }) {
this.id = id;
this.name = name;
this.age = age;
}
}
const user1 = new User({id: 1, name: 'Rick' });
const user2 = new User({id: 1, name: 'Rick', age: undefined });
const user3 = new User({id: 1, name: 'Rick', age: new Date() });
// const user4= new User({id: 1, name: 'Rick', age: new Date(), addProp: [] }); // <== Error
Typescript documentation does have a section on Parameter Destructuring
If we find it too verbose, we can define a type alias
for the type of parameters of the constructor, like ...
type UserParams = { id: number, name: string, age?: Date };
class User {
protected id: number;
protected name: string;
protected age?: Date;
constructor({id, name, age }: UserParams) {
this.id = id;
this.name = name;
this.age = age;
}
}
const user1 = new User({id: 1, name: 'Rick' });
const user2 = new User({id: 1, name: 'Rick', age: undefined });
const user3 = new User({id: 1, name: 'Rick', age: new Date() });
// const user4= new User({id: 1, name: 'Rick', age: new Date(), addProp: [] }); // <== Error
We could have used the class User
as a type in the constructor parameter, but the problem is that all properties of class User
are marked protected
and passing-in arguments with those names of the properties will error out. However, if we can make these properties public
, we should be able to achieve what we want...
class User {
id: number; // <== protected modifier gone
name: string; // <== protected modifier gone
age?: Date; // <== protected modifier gone
constructor({ id, name, age }: User) {
this.id = id;
this.name = name;
this.age = age;
}
}
const user1 = new User({ id: 1, name: 'Rick' });
const user2 = new User({ id: 1, name: 'Rick', age: undefined });
const user3 = new User({ id: 1, name: 'Rick', age: new Date() });
// const user4 = new User({ id: 1, name: 'Rick', age: new Date(), addProp: [] }); // <== Error
CodePudding user response:
You can reduce your implementation to one line:
class User {
constructor(protected id: number, protected name: string, protected age?: Date) { }
}
// {
// "id": 1,
// "name": "2",
// "age": undefined
// }
const result = new User(1, '2') // ok