javascript - 如何在 Typescript 中检查自定义接口类型
问题描述
我有
interface A {
a_id: string;
name: string;
}
interface B {
b_id: string;
name: string;
}
现在,我想检查一个对象说:
const myObj : A|B = {b_id: '1', name: 'one'};
如何检查类型并确定它是否属于A
或B
?
我尝试了几个链接,但获取类型不应该更容易吗?
解决方案
更新:所述问题并不表明请求能够在不检查属性的情况下区分类型。不幸的是,这是不可能的;TypeScript 编译为 JavaScript,这是实际运行的。并且 TypeScript 的类型系统,在其中找到类似A
和的接口,在编译代码时会B
被完全擦除。所以没有A
或B
在运行时检查。
如果您希望能够在运行时区分myObj
isA
或B
,则需要编写执行此操作的 JavaScript 代码……例如检查属性。您可以做的是使用 TypeScript 来帮助您编写此代码并为其输入类型,以便编译器也了解您的属性检查将 an 缩小A | B
到 anA
或 a B
。这就是这个答案的其余部分(以及另一个问题的答案)告诉你的。祝你好运!
另一个问题的答案建议您编写一个用户定义的类型保护函数,它肯定会起作用;这个想法是你告诉编译器你认为什么是区分A
and的好方法B
,它会让你使用那个函数来做到这一点。
在您的情况下,一种更简单的方法是使用in
运算符,它可以用作类型保护(从 TypeScript 2.7 开始)。例如:
declare const obj: A | B;
if ("b_id" in obj) {
// obj is a B in here
console.log(obj.name.toUpperCase());
} else {
// obj is an A in here
console.log(obj.a_id.toUpperCase());
}
请注意,这在技术上是不安全的,因为可能有一个无法以A | B
这种方式区分的类型的对象:
function getEvilAorB(): A | B {
interface EvilA extends A {
b_id: number;
}
const evilA: EvilA = { name: "", a_id: "", b_id: 123 };
return evilA; // okay, EvilA extends A extends A | B
}
请注意,它getEvilAorB()
返回一个 valid A
,因此它是一个 valid ,但不幸的是,由于 numeric属性A | B
,它将无法通过上述测试:name
const evilA = getEvilAorB();
if ("b_id" in evilA) {
console.log(evilA.b_id.toUpperCase()); // compiles but at runtime
// TypeError! evilA.name.toUpperCase is not a function
}
如果您不关心这种边缘情况,那么in
类型保护可能就足够了。否则,您应该考虑编写用户定义的类型保护,或者使您的接口成为可区分联合的成员,这是让编译器区分联合成员的常规且受支持的方式。
希望有帮助;祝你好运!
推荐阅读
- python - 如何在python中制作分隔符
- java - Spring Kafka如何动态创建多个消费者
- tensorflow - 将 K.function 与 K.gradients 一起使用时出错
- github - 如何将 WSO2 与 GitHub 集成?
- javascript - Cookie 可能返回错误的格式
- javascript - Jquery 和 Flask 的问题
- javascript - 后端突然停止工作并抛出此错误“找不到模块'../../cast/boolean'”
- python - Tensorboard 不显示来自估计器的任何标量摘要
- python - 将 random.choice 变成可变的
- android - 那是我吗?还是 android studio 更改了我的整个 build.gradle 代码,现在我的整个项目都搞砸了?