为什么Sorbet不对Hash类型不匹配的代码报错?有何解决办法?
为什么Sorbet没有抛出类型错误
这个问题是Sorbet默认的哈希类型推导规则导致的:
当你使用空哈希字面量hash = {}声明变量时,Sorbet默认会将该哈希的类型推导为T::Hash[T.untyped, T.untyped]。而T.untyped类型和任意类型都兼容,因此哪怕你后续给这个哈希插入了Integer类型的键值,Sorbet也不会主动标记它和T::Hash[String, String]的类型不匹配。
让Sorbet捕获这类错误的方法
你可以通过以下几种方式实现:
- 显式为哈希变量添加类型标注
声明变量时用T.let明确指定哈希的类型,Sorbet就会按照标注的类型做全链路检查:# 标注后Sorbet会校验该哈希的所有操作,也会校验传参是否匹配 hash = T.let({}, T::Hash[Integer, Integer]) hash[1] = 1 foo(hash) # 此处会直接抛出类型不匹配错误 - 开启严格哈希字面量推导参数
运行Sorbet检查时添加--strict-hash-literals命令行参数,开启后空哈希不会被默认推导为untyped类型,而是会根据后续赋值的内容自动收窄类型。在你的示例中,插入1 => 1后哈希会被推导为T::Hash[Integer, Integer],传入foo方法时就会触发错误。 - 提高文件的类型严格级别
将文件头部的# typed: true修改为# typed: strict,该模式下要求所有顶层变量必须显式标注类型,避免隐式的untyped类型导致的漏判。 - 直接使用非空哈希字面量初始化
如果不需要动态构建哈希,直接用hash = {1 => 1}的方式初始化,Sorbet可以直接推导出正确的T::Hash[Integer, Integer]类型,传入foo时也会触发错误。
内容的提问来源于stack exchange,提问作者sync101
相关产品推荐
相关产品推荐

