For example, I have a vehicle object as
vehicle: {
make: { //say type Make
name: "acura",
model: "rdx"
},
user: { //say type User
name: "abc",
age: 30
},
addr: { //say type Address
number: 12,
street: 'xyz ave'
}
}
I want to write a function that can either receive the entire object or a partial object. So I did
function display({make}: {make?: Make} = {}, {user}: {user?: User} = {}, {addr}: {addr?: Address} = {}): void {
if(make) {
console.log(make.name);
}
if(user) {
console.log(user.name);
}
if(addr) {
console.log(addr.num);
}
}
display(vehicle); // Should display acura, abc, 12
display(vehicle.user); // Should display abc
Now, the above function works if I just pass the make or the entire vehicle object. Except of course it takes it as only the first parameter and the rest are undefined. How do I destructure the params properly to pass either a partial object or the entire object?
CodePudding user response:
You can use overloads and type guards
function display(vehicle: Vehicle): void;
function display(make: Make): void;
function display(user: User): void;
function display(addr: Address): void;
function display(target: Vehicle | Make | User | Address): void {
if (isvehicle(target)) {
target
//^?
}
if (ismake(target)) {
target
//^?
}
if (isuser(target)) {
target
//^?
}
if (isaddr(target)) {
target
//^?
}
}
function isvehicle(v: any): v is Vehicle {
return v && v.make && v.user && v.addr;
}
function ismake(v: any): v is Make {
return v && v.name && v.model;
}
function isuser(v: any): v is User {
return v && v.name && v.age;
}
function isaddr(v: any): v is Address {
return v && v.num && v.street;
}
You can make the type guards as strict/correct if necessary.