TypeScript中的超类型约束

时间:2015-11-13 23:13:16

标签: typescript

我正在尝试使用updeep库。使用updeep的典型示例是这样的:

var person = {
  name: {
    first: 'Jane',
    last: 'West'
  }
};

var result = u({ name: { first: 'Susan' } }, person);

这里的想法是result将成为person的克隆,但name.first的值已更改。你可以想象这个函数u,在TypeScript中定义为:

function u<T>(changes: {}, obj: T): T { ... }

这捕获了第二个参数的类型也是函数的返回类型的事实。但它没有表达的是changes应该是T超类型

我想要的是对第一个参数进行某种类型检查。关键是changes争论中出现的值应该都存在于T类型参数中,并与那里的对应类型相匹配。表达这一点允许我们检查changes参数以确保它对T类型有意义(即,T的超类型)

我不确定TypeScript中是否可以这样做。在像Java这样的语言中,您有super关键字,它可以用来描述类型参数的约束。

虽然TypeScript不允许,但类似的东西表达了我想要的东西:

function u<T extends U,U extends {}>(changes: U, obj: T): T { ... }

有人建议如何表达这个吗?拥有一个用于执行此类转换的类型安全系统会很棒。

感谢。

2 个答案:

答案 0 :(得分:1)

这样的问题有一个未解决的问题,在这里称为“部分类型”:https://github.com/Microsoft/TypeScript/issues/4889

Facebook的Flow有类似的(但是intentionally undocumented)$ Shape&lt;&gt;类型,可以在React setState()的输入中看到。

所以基本上,不,没有这样的功能可以自动执行此操作。但是,您可以手动执行此操作:

interface IPartialPerson {
  name?: {
    first?: string;
    last?: string;
  };  
  someOptionalProperty?: string;
}

interface IPerson extends IPartialPerson {
  name: {
    first: string;
    last: string;
  };
}

就个人而言,我更愿意避免使用后者,并尽可能使用可选属性。强制性财产并不能真正保护您免受任何伤害;即使它们看起来像它们,它们也不是non-nullable

答案 1 :(得分:1)

自TypeScript 2.1以及Partial<T>

以来,这已经成为可能

原始问题将通过

解决

function u<T>(changes: Partial<T>, obj: T): T { ... }