【问题标题】:How to set lower-bound to type parameters in TypeScript?如何在 TypeScript 中设置类型参数的下限?
【发布时间】:2017-07-28 04:58:02
【问题描述】:

在 TypeScript(我的版本:2.1.1)中,可以像这样设置类型参数的上限:

class Animal {}
class Cat extends Animal {}
class Kitten extends Cat{}

function foo<A extends Animal>(a: A) { /* */ }

如何设置A 的下限?以下代码不起作用:

class Animal {}
class Cat extends Animal {}
class Kitten extends Cat{}

function foo<A super Kitten>(a: A) { /* */ }

会导致编译错误。

TypeScript repo 的 GitHub 问题 #13337 中的人建议使用

function foo <X extends Y, Y>(y: Y) { /* */ }

到下限YX。但这不包括我的情况,其中X 是实际类型而不是类型参数。

关于如何降低类型参数的任何想法?

【问题讨论】:

  • 为什么需要这样做?如果A super Kitten 那么A 显然是KittenCatAnimal,你将如何从缩小范围中受益?你能举一个真实的例子来说明它是如何使用的吗?
  • 由于您使用了类似 Java 的语法,我假设您从 Java 的逆变性中获得了灵感。事实上,Java 只允许在通配符(例如Comparable&lt;? super String&gt;)中使用逆变,而不是在类型参数声明上下文(泛型类、接口和/或方法的声明)中。正如其他人指出的那样,原因是在这种情况下,下限将没有意义。

标签: generics typescript types type-bounds


【解决方案1】:

TypeScript 还不支持泛型的下限。目前正在讨论此类建议 - TypeScript 开发人员不确定此类功能是否必要。因此,我们只能等待并希望他们会同意实施。

在此处查看 TypeScript 问题跟踪器中的问题 - https://github.com/Microsoft/TypeScript/issues/14520

【讨论】:

    【解决方案2】:

    两个问题。第一个是实用的:

    约束无效

    我不认为这是一个概念上有意义的限制。这听起来像是参数逆变的变体。您的意思是您愿意接受任何属于Kitten 超类的类型。

    问题在于以下也成立:

    • KittenCat 的子类。
    • CatAnimal 的子类。

    到目前为止,我们都很好。但还要考虑以下几点:

    • 与任何 TypeScript class 一样,AnimalObject 的子类,Object 是全局根类型。
    • 所有内容都被视为 TypeScript Object

    所以A 必须是Kitten 的超类的限制实际上意味着A 只能被假定为Object,这意味着类型约束没有意义,因为所有类型都满足该要求。

    违反里氏替换原则

    另一个问题是这违反了Liskov Substitution Principle,它规定任何对类T 成立的属性也应该对其子类成立。因此,放置一个接受 Cat 类的对象但不接受其子类 Kitten 的约束将违反该规则。

    【讨论】:

    • 我认为你的答案是错误的,因为 Java 中使用了下限。
    • 我认为 FstTesla 在 cmets 中对问题的回答解决了我遗漏了什么?
    • 查看我在回答这个问题时提供的链接。有很多讨论。
    猜你喜欢
    • 1970-01-01
    • 2019-06-13
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多