(请注意,这在sorbet.run上是不可复制的,据我所知,只能在本地复制一份Sorbet )
我本来希望可以使用类型化结构特征创建一个方法签名,其中一个参数是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})本质上,当您键入这个文件时,它会抱怨当需要一个Struct时,会传入一个散列。我的问题是:如何为具有特定参数的散列定义有效签名?结构显然不在这里工作。虽然我还没有试过形状,但根据文档,它们是非常有限的,所以如果可能的话,我宁愿不使用它们。
关于泛型的文献提到了散列,但似乎表明只有当哈希的键和值都是相同类型时(例如,Hash<Symbol, String>要求所有键都是符号,所有值都是String),并且没有提供任何方法(据我所知)来定义带有特定键的哈希,才能使用哈希。
谢谢!
发布于 2019-06-30 21:11:23
实际上,您必须选择一种不同的方式(您已经提到过的三种方式):
T::Hash[KeyType, ValueType]。这允许您在调用将其作为param的方法时使用{}语法,但强制您对每个条目使用相同类型的键和值。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]
endT::Struct。这迫使您使用MyStruct.new(prop1: x, prop2: y, ...)调用该方法。它们都是有效的,其中4和5是给你最安全的类型。在这两者中,4是调用者中最灵活的,但5是您知道Sorbet在短期/中期内不会改变支持的。
https://stackoverflow.com/questions/56828043
复制相似问题