(请注意,这不能在 sorbet.run 上重现,据我所知,它只能用 Sorbet 的本地副本重现)
我希望我可以使用Typed Structs 功能来创建一个方法签名,其中一个参数是options散列,但这不起作用:
# typed: true
require 'sorbet-runtime'
extend T::Sig
class OptionsStruct < T::Struct
prop :x, Integer, default: 1
end
sig { params(options: OptionsStruct).void }
def method(options)
puts options.x
end
# This works
method(OptionsStruct.new({x: 2}))
# This causes the typechecker to throw.
method({x: 2})
Run Code Online (Sandbox Code Playgroud)
本质上,当您键入检查此文件时,它会抱怨在需要 Struct 时传入哈希值。我的问题是:如何为具有特定参数的哈希定义有效签名?结构在这里显然不起作用。虽然我没有尝试过 Shapes,但根据文档,它们非常有限,所以如果可能的话,我宁愿不使用它们。
关于泛型的文档提到了哈希,但似乎表明它们只能在哈希的键和值都是相同类型的情况下Hash<Symbol, String>才能使用(例如,要求所有键都是符号,所有值都是字符串),并且不提供任何方式(据我所知)用特定的键定义一个散列。
谢谢!
从本质上讲,您必须选择采用多种方式之一(您已经提到了三种方式):
T::Hash[KeyType, ValueType]. 这允许您{}在调用将其作为参数的方法时使用该语法,但强制您对每个条目使用相同类型的键和值。T::Hash[KeyType, Object]. 这在值的类型上更加灵活……但是您会丢失类型信息。T::Hash[KeyType, T.any(Type1, Type2, ...). 这是介于 1 和 2 之间的中间地带。T::Struct给调用者使用的情况下对这样的东西进行建模的最好方法:sig { params(options: {x: Integer}).void }
def method(options)
puts options[:x]
end
Run Code Online (Sandbox Code Playgroud)
T::Struct像你一样使用 a 。这迫使您调用该方法MyStruct.new(prop1: x, prop2: y, ...)它们都是有效的,其中 4 和 5 是为您提供最多类型安全性的。在这两者中,4 对调用者来说是最灵活的,但 5 是你知道Sorbet在短期/中期不会改变支持的那个。
| 归档时间: |
|
| 查看次数: |
1323 次 |
| 最近记录: |