Sorbet中的T.type_parameter高级用法

时间:2019-08-11 23:23:33

标签: sorbet

要编写通用方法,我只发现了this example on sorbet.runsorbet.org/docs当前未提及type_parameter。因此,我对T.type_parameter的高级用法有一些疑问。

  1. 限制父类型

如何指定仅允许某种类型的子类型? (与通用类相同,使用type_member) 例如。只允许使用“ Enumerable”类型,因此我可以在该对象上调用“ Enumerable”中的所有内容。

  1. 工厂方法

我有一个实例化给定类的对象的方法。 (例如,因为它使用的参数应保持私有状态) 我该如何签名?

→ View on sorbet.run

#typed: true

class Animal
  def initialize(secret_of_nature); end
end

class Sidewinder < Animal
  def rattle; end
end


class Nature
  extend T::Sig

  sig {params(animal_cls: T.class_of(Animal)).returns(Animal)}
  def self.factory(animal_cls)
    animal_cls.new(@secret_dna)
  end
end


Nature::factory(Sidewinder).rattle
# => Method rattle does not exist on Animal

1 个答案:

答案 0 :(得分:0)

猜猜我找到了答案。就在五天前的提交日志中。

Add type bounds to generics (#1392)

看起来像lower的小型测试也可以省略。

→ View on sorbet.run

# typed: true

class Animal; end
class Cat < Animal; end
class Serval < Cat; end

class A
  extend T::Generic
  T1 = type_member(lower: Serval, upper: Animal)
end

# should pass: Cat is within the bounds of T1
class B1 < A
  extend T::Generic
  T1 = type_member(fixed: Cat)
end

# should fail: String is not within the bounds
class B2 < A
  extend T::Generic
  T1 = type_member(fixed: String)
     # ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: parent lower bound `Serval` is not a subtype of lower bound `String`
     # ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: upper bound `String` is not a subtype of parent upper bound `Animal`
end

# should pass: the bounds are a refinement of the ones on A
class C1 < A
  extend T::Generic
  T1 = type_member(lower: Serval, upper: Cat)
end

# should fail: the bounds are wider than on A
class C2 < A
  extend T::Generic
  T1 = type_member(lower: Serval, upper: Object)
     # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: upper bound `Object` is not a subtype of parent upper bound `Animal`
end

# should fail: the implicit bounds of top and bottom are too wide for T1
class D1 < A
  T1 = type_member
     # ^^^^^^^^^^^ error: parent lower bound `Serval` is not a subtype of lower bound `T.noreturn`
     # ^^^^^^^^^^^ error: upper bound `<any>` is not a subtype of parent upper bound `Animal`
end

https://github.com/sorbet/sorbet/blob/417c1087dc3a5f76665fc49459b85c297e1ffac4/test/testdata/infer/generics/bounds_super.rb