经常有用户反馈,他们如下的代码会在 IDE 中报错:
property(Material)
public material: Material = null;
出错原因
material: Material
将 material
字段声明为 Material
类型,这个意思就是 在任何时候 拿到 material
他都是一个 Material
。
= null
,告诉它将 material
初始化为 空值 null
。那么与上条说法违背。
这便是,TypeScript 的 严格类型检查。它要求你将类型对上号。TypeScript 编辑器是默认开启该选项的,Creator 也不例外。
解决办法
匹配它们的类型
既然 material
初始化为 空值 null
,那么它的确可能是空值,那么可以这样声明:
public material: Material | null = null;
material: Material | null
将 material
声明为 “既可能是 Material
,也可能是 null
”。
这样的缺点是:
-
后续使用
material
的时候需要判定它是否是空值,否则 TypeScript 会报告给你:它可能是空值,你需要处理是空值的情况。 -
写法真长。
断言
为什么 material
可能是空值?因为它确实一开始是空值,然后在 Cocos Creator 中我们通过拖拖拉拉之后,Creator 帮我们赋值进去。
那我们就想办法告诉 TypeScript,它就是 Material
,虽然它一开始是空值,但你别管,我后续任何时候访问它,它都是 Material
。
有以下几种写法来做这件事:
一
material: Material = null!;
感叹号 !
告诉 TypeScript 强制 将 null
转换为 Material
类型。
二
同样地,初始化为 undefined
也没问题:
material: Material = undefined!;
感叹号 !
告诉 TypeScript 强制 将 undefined
转换为 Material
类型。
三
其实,在标准的 JavaScript 语法里,是可以不给初始化式的,这样的字段将被初始化为 undefined
:
class C {
@property(Material)
material; // undefined
}
在 TypeScript 里也允许这么做,不过你得提示一下 TypeScript,以上它跳过这里的类型检查:
material!: Material;
OK,这里你将得到一个虽然声明为 Material
,但是初始化为 undefined
的字段。
和 TypeScript 严格空值检查说拜拜
当然了,如果你是非常不喜欢 TypeScript 的类型系统,你更喜欢所有事 靠自己确保,那么你可以关闭严格类型检测。在 <项目目录>/tsconfig
里,加上选项:
"extends": "./temp/tsconfig.cocos.json",
"compilerOptions": {
"strictNullChecks": false // 关闭它
}
即使不是必须,我们仍然建议您保留这个选项,因为它可能帮你检测到非常多潜在的 Could not read "xx" property of null or undefined
错误。