cocos 3.0 类型分配报错,对象可能为 “null“

cocos 3.0 类型分配报错,对象可能为 “null“

严格模式:“null” 问题
从 JavaScript 转入 TypeScript 的同学可能被一些“类型问题”所困扰。
看这样一个问题:

class C {
    material: Material = null;
}

这段代码在 IDE 中会报错,报错源头是属性 material 的声明。
有一种情况是,material 属性仅在初始化时是空值,但是后续任何时候访问都是有值的。例如,给该属性附加 @property 装饰器时,就可以在编辑器中编辑该字段,拖拖拉拉之后由 Creator 帮我们赋值该字段。
那我们如何向 TypeScript 传达这种信息呢?

我们来分析一下报错的原因,material: Material 将 material 字段声明为 Material 类型,这个意思就是在任何时候拿到 material 它都是 Material 类型。
初始化式 = null 告诉它将 material 初始化为 空值 null,与上条说法违背。
这便是,TypeScript 的严格类型检查。它要求你将类型对上号。TypeScript 编辑器是默认开启该选项的,Creator 也不例外。
既然知道了出错原因,那么我们就可以有以下几种思路去解决。
正确描述它的类型为:既可能是 Material,也可能是 null
向 TypeScript 类型系统表达:我只是初始化为 null,后续使用时候其实都是 Material
关闭 TypeScript 对空值的检查。

可空类型

我们可以将 material 的类型描述为既可能是 Material,也可能是 null:

material: Material | null = null;

这样初始化为 null 就顺理成章了。

然而,这样的缺陷是当你后续访问 material 时,TypeScript 要求你处理空值的情况。例如:

console.log(this.material.name);

TypeScript 类型系统会提示你:
this.material 可能是空值 null,无法访问 null 的属性。

但是,只要 TypeScript 在此处知道它一定是不为空的,
它就会收起这条错误:

if (this.material) {
    console.log(this.material.name);
}

因为你做了判断,
当运行到 if 语句块内的时候,this.material 一定是不为空的,
因此可以访问 name属性。

表达式非空断言
每次使用的时候都要用 if 语句判断一下实在有些繁琐,况且 if 语句在运行时是会去执行的。
如果你一定能确保“在运行到这里的时候 this.material 一定非空”,那么我们可以用TypeScript 非空断言语法来表达:

console.log(this.material!.name);

感叹号 ! 称作 非空断言操作符,它断言前面的表达式是非空的。
注意此感叹号是 TypeScript 特有的,仅为类型目的;编译后,会直接移除。

我们还可在初始化时就作此断言:

material: Material = null!; // 相当于将 `null` 强制转换为了 `Material` 类型

还一个经常用于非空断言的地方是 Node.getComponent(),此方法返回的是可能为空的组件。如果能确保组件一定存在,则可以通过非空断言来避免 if 判断。

显式赋值断言
在标准的 JavaScript 语法里,是可以不给初始化式的,这样的字段将被初始化为 undefined:

class C {
  @property(Material)
  material; // undefined
}

在 TypeScript 里也允许这么做,不过你得提示一下 TypeScript,以让它跳过这里的类型检查:

material!: Material;

属性名后的感叹号称为 显式赋值断言(Definite Assignment Assertion) 2,它告诉 TypeScript 此字段在别处初始化。
OK,这里你将得到一个虽然声明为 Material,但是初始化为 undefined 的字段。

禁用空值检查
当然了,如果你是非常不喜欢 TypeScript 的类型系统,你更喜欢所有事靠自己确保,那么你可以关闭严格类型检测。在 <项目目录>/tsconfig.json 里,加上选项:

"extends": "./temp/tsconfig.cocos.json",
"compilerOptions": {
  "strictNullChecks": false // 关闭它
}

需要提醒的是,官方并不鼓励这种做法,因为严格空值检查能够减少 JS 代码运行时的一些低级报错。

另外上方的代码在cocos中不显示报错了 但是vscode中还是存在
解决ts中的报错

单行忽略
// @ts-ignore

忽略全文
// @ts-nocheck

取消忽略全文
// @ts-check

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值