Skip to content

类型断言与类型收束

本文参考了 Mofeng 大佬的文章:Filter 与 type predicate

Screeps 常见建筑类型

在正式讲解之前,先了解 Screeps 中常见的建筑相关类型:

Screeps 中常见的建筑相关类型 >
main.ts

代码编辑器加载中...

可以看到:

  • AnyStructure:所有建筑类型的联合类型
  • AnyOwnedStructure:所有拥有 owner 属性的建筑类型联合
  • AnyStoreStructure:所有拥有 store 属性的建筑类型联合
  • StructureConstant:所有建筑类型字符串的联合类型
  • BuildableStructureConstant:所有可建造建筑类型字符串的联合类型
  • 具体建筑类型以 Structure 前缀命名,如 StructureContainerStructurePortalStructureRoadStructureWall

获取指定类型的建筑

在 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

代码编辑器加载中...

Released under the MIT License