如何在 TypeScript 运行时检查对象类型?

新手上路,请多包涵

我试图找到一种方法将对象传递给函数并在运行时检查它的类型。这是一个伪代码:

 function func (obj:any) {
    if(typeof obj === "A") {
        // do something
    } else if(typeof obj === "B") {
        //do something else
    }
}

let a:A;
let b:B;
func(a);

But typeof always returns "object" and I could not find a way to get the real type of a or b . instanceof 也不起作用并返回相同的结果。

知道如何在 TypeScript 中做到这一点吗?

原文由 Eden1971 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 683
2 个回答

编辑:我想向来自搜索的人指出,这个问题专门处理非类类型,即由 interfacetype 别名定义的对象形状。对于类类型,您可以使用 JavaScript 的 instanceof 来确定实例来自的类,TypeScript 会自动缩小类型检查器中的类型。

类型在编译时被剥离并且在运行时不存在,因此您无法在运行时检查类型。

您可以做的是检查对象的形状是否符合您的期望,TypeScript 可以在编译时使用返回 true 的 用户定义类型保护 来断言类型(带注释的返回类型是形式的“类型谓词” arg is T ) 如果形状符合您的期望:

 interface A {
  foo: string;
}

interface B {
  bar: number;
}

function isA(obj: any): obj is A {
  return obj.foo !== undefined
}

function isB(obj: any): obj is B {
  return obj.bar !== undefined
}

function func(obj: any) {
  if (isA(obj)) {
    // In this block 'obj' is narrowed to type 'A'
    obj.foo;
  }
  else if (isB(obj)) {
    // In this block 'obj' is narrowed to type 'B'
    obj.bar;
  }
}

操场上的例子

类型保护实现的深度取决于您,它只需要返回 true 或 false。例如,正如卡尔在他的回答中指出的那样,上面的示例仅检查是否定义了预期的属性(按照文档中的示例),而不是为它们分配了预期的类型。对于可空类型和嵌套对象,这可能会变得很棘手,由您决定进行形状检查的详细程度。

原文由 Aaron Beall 发布,翻译遵循 CC BY-SA 4.0 许可协议

您应该使用“in”运算符来缩小范围。 参考

type Fish = { swim: () => void };
type Bird = { fly: () => void };

function move(animal: Fish | Bird) {
  if ("swim" in animal) {
    return animal.swim();
  }

  return animal.fly();
}

原文由 sanket kheni 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进