类型断言与类型收束
本文参考了 Mofeng 大佬的文章:Filter 与 type predicate
Screeps 常见建筑类型
在正式讲解之前,先了解 Screeps 中常见的建筑相关类型:
Screeps 中常见的建筑相关类型
main.ts
代码编辑器加载中...
可以看到:
AnyStructure
:所有建筑类型的联合类型AnyOwnedStructure
:所有拥有 owner 属性的建筑类型联合AnyStoreStructure
:所有拥有 store 属性的建筑类型联合StructureConstant
:所有建筑类型字符串的联合类型BuildableStructureConstant
:所有可建造建筑类型字符串的联合类型- 具体建筑类型以 Structure 前缀命名,如
StructureContainer
、StructurePortal
、StructureRoad
、StructureWall
等
获取指定类型的建筑
在 Screeps 中,可以通过 room 对象的 find 方法查找建筑。但如果不加处理,返回的建筑类型为 AnyStructure。
room.find 返回值
main.ts
代码编辑器加载中...
类型断言指定类型
常见做法是使用类型断言,手动指定返回值类型。例如:
断言类型
main.ts
代码编辑器加载中...
注意:使用类型断言时,请确保你对断言处的类型有充分了解,避免类型错误。
类型收束与类型推断
除了类型断言,还可以通过类型收束实现更优雅的类型推断。
类型收束常用方法之一是使用 is
关键字定义类型保护函数。
在 TypeScript 中,如果一个函数返回 boolean
,可以用 is
关键字标注返回值为 true
时的类型。
如下例,utils.ts
中定义了类型保护函数 isContainer
,用于判断建筑是否为容器类型。在 main.ts
中,通过该函数过滤建筑。
类型收束自动推断类型
main.tsutils.ts
代码编辑器加载中...
显然,不可能为每种建筑类型都单独定义判断函数,这样既繁琐又难维护。幸运的是,Screeps 类型声明文件中提供了 ConcreteStructure
这种映射类型,可以通过建筑类型常量直接映射到具体类型。
例如:
ts
// StructureContainer
type Container = ConcreteStructure<STRUCTURE_CONTAINER>;
我们可以改造之前的判断函数,实现更通用的建筑类型判断:
通用的建筑类型判断函数
main.tsutils.ts
代码编辑器加载中...