Is there a way to determine whether a generic Object matches a certain Type? I have an ngOnChanges method where I'd like to perform different actions based on the type of the generic returned.
Here's a simplified example of what I'm trying to do. Here's the response object:
myResponseData = {
name: 'fu'
address: '123 ABC Lane'
}
Can I determine if this matches either one of these objects?
const personModel = {
name: string;
address: string;
}
const placeModel = {
city: string;
country: string;
}
I've tried using a condition like this to match but the response data matches both conditions:
if(myResponseData as personModel) {}
else if(myResponseData as placeModel) {}
Is there a condition that'll allow me to match a generic against a Type?
CodePudding user response:
I can propose two solutions:
Type predicates type predicates
Typescript playground using type predicates
Sample code
interface PersonModel {
name: string;
address: string;
}
interface PlaceModel {
city: string;
country: string;
}
const isPersonModel = (input: any): input is PersonModel => {
const requiredProps: Array<keyof PersonModel> = ["name", "address"];
return requiredProps.every(prop => input[prop] !== undefined);
}
const isPlaceModel = (input: any): input is PlaceModel => {
const requiredProps: Array<keyof PlaceModel> = ["city", "country"];
return requiredProps.every(prop => input[prop] !== undefined);
}
const person = { name: "Peter", address: "something"};
const place = { city: "London", country: "UK"};
console.log(`Is person a person: ${isPersonModel(person)}`);
console.log(`Is person a place: ${isPlaceModel(person)}`);
const genericInput = {};
if (isPersonModel(genericInput)) {
//typescript believes it is a PersonModel
const address = genericInput.address;
const country = genericInput.name;
}
Using classes and instanceof operator
class PersonModel {
constructor(public name: string, public address: string){}
}
class PlaceModel {
constructor(public city: string, public country: string){}
}
const getObject = ():any => {
if (Date.now() % 2 === 0) {
console.log("generating person model");
return new PersonModel("Peter", "Street 1");
} else {
console.log("generating place model");
return new PlaceModel("Berlin", "Germany");
}
}
const randomObject = getObject();
if (randomObject instanceof PlaceModel) {
console.log("Object identified as Place model");
}
if (randomObject instanceof PersonModel) {
console.log("Object identified as PersonModel");
}