我有一个 JSON 文件,其中包含两种不同类型的对象。我想根据它们的类型迭代 JSON。为了说明我的问题,我创建了两种不同类型的对象
Animal
和 Person
现在我想检查对象的类型,是动物还是人。
type Animal = {
name: string;
legs: number;
}
type Person = {
name: number;
}
const checkType = (isAnimalOrPerson: Animal | Person) =>{
if(isAnimalOrPerson instanceof Animal){
console.log("animal type");
}
else{
}
}
如果条件为:
"Animal" only refers to a type, but is being used as a value here.
,我会收到错误
type
的“问题”在于它是一个仅在开发过程中存在的概念;一旦你转译,它就会消失,并且 TypeScript 无法预见你可能传递的运行时值的形状(除非你进行断言,即显式检查对象具有哪些属性)。如果您想进行类型检查,则必须以另一种方式进行,例如使用类,然后该方法仅在您实际实例化该类时才有效(而不是仅将其用作形状):
class Animal {
name: string;
age: number;
legs: number;
}
class Person {
name: string;
age: number;
job: string;
education: string;
}
let a: Animal = new Animal();
let b: Animal = { name: "Rex", legs: 4, age: 3 };
let c = new Person();
function checkType(arg: Animal | Person): string {
if (arg instanceof Animal) {
return "This is an animal";
} else if (arg instanceof Person) {
return "This is a person";
}
return "Can't tell";
}
console.log(checkType(a)); // This is an animal
console.log(checkType(b)); // Can't tell
console.log(checkType(c)); // This is a person
有多种方法可以检查
PersonorAnimal
值是否也满足Animal
。
if ('legs' in toBeDetermined) {
// toBeDetermined should be `Animal` in this block
}
Animal
一个unique symbol
并检查它们const animalTag: unique symbol = Symbol("Animal tag");
type Animal = {
__brand__: typeof animalTag;
name: string;
legs: number;
}
if (toBeDetermined.__brand__ === animalTag) {
// toBeDetermined can be coerced manually into Animal
}
我更喜欢 1,因为
Animal
具有不相交的属性 legs
。
要添加到 user-id-14900042 的第一点,您可以编写一个函数来检查对象中的字段以及该字段的类型以缩小范围。
例如
function isAnimal(object: object | undefined): object is Animal {
return !!object &&
'name' in object &&
typeof object.name === 'string' &&
'legs' in object &&
typeof object.legs === 'number';
}