ArkTS中语法报错:`'MyMarsData' only refers to a type, but is being used as a value here.`是怎么回事?

HarmonyOS Next中语法报错:'MyMarsData' only refers to a type, but is being used as a value here. <ArkTSCheck>是怎么回事?

interface MyMarsData{
  xxx:boolean;
}
if(msgPackDecodedObj instanceof MyMarsData){
    let isXXX = (msgPackDecodedObj as MyMarsData).xxx;
}

instanceof报错:'MyMarsData' only refers to a type, but is being used as a value here. <ArkTSCheck>

阅读 2k
avatarAI BotBETA

在TypeScript(以及ArkTS,假设它是TypeScript的一个变种或扩展)中,你遇到的错误是因为你试图使用instanceof操作符来检查一个对象是否是某个接口类型的实例。然而,instanceof操作符在TypeScript中只能用于检查对象是否是某个类的实例,而不能用于检查对象是否符合某个接口的形状。

在你的代码中,MyMarsData是一个接口,而不是一个类。因此,你不能使用instanceof来检查一个对象是否是MyMarsData的实例。

解决这个问题的一种方法是使用类型断言来确保msgPackDecodedObj符合MyMarsData接口的形状,而不是使用instanceof。你已经在代码中使用了类型断言(msgPackDecodedObj as MyMarsData),这是正确的做法。

然而,如果你仍然想要进行某种类型的检查,你可以使用TypeScript的类型守卫。类型守卫是一种表达式,其结果可以在编译时确定类型的窄化。对于接口,你可以使用is操作符配合一个用户自定义的类型守卫函数。

下面是一个示例:

interface MyMarsData {
  xxx: boolean;
}

function isMyMarsData(obj: any): obj is MyMarsData {
  return obj && 'xxx' in obj && typeof obj.xxx === 'boolean';
}

if (isMyMarsData(msgPackDecodedObj)) {
  let isXXX = msgPackDecodedObj.xxx;
}

在这个示例中,isMyMarsData函数是一个类型守卫,它检查一个对象是否有xxx属性,并且该属性的类型是否为boolean。如果对象符合这些条件,那么isMyMarsData函数将返回true,并且TypeScript会窄化msgPackDecodedObj的类型为MyMarsData。这样,你就可以安全地访问msgPackDecodedObj.xxx了。

1 个回答

因为interface接口定义了一个对象的结构或者一个函数的签名,它只是一个类型,不会被编译到 JavaScript(这一点和java的interface是有差异的)。接口主要用于类型检查和代码提示。而类定义了一个对象的结构以及与之相关的方法。类会被编译为 JavaScript,并在运行时使用。

这里面要instanceof 后需要的是一个真正的class类型,所以这里的MyMarsData要改成class

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