TypeScript 使用Exact、Subset、Superset进行类型Assert

jjhzyzn0  于 8个月前  发布在  TypeScript
关注(0)|答案(5)|浏览(73)

我已经遇到过几次关于类型限制的报错,例如:

  1. res.json(<Foo>{foo:'bar'});

上面的cast/assertion语句在匿名对象没有Foo类型的所有字段时仍然有效。
例如,我遇到的问题是: https://stackoverflow.com/questions/53328459/prevent-compilation-unless-all-fields-exist
这个功能请求是希望实现类似以下内容的功能:

  1. res.json(Exact<Foo>{foo:'bar'});
  2. res.json(Subset<Foo>{foo:'bar'});
  3. res.json(Superset<Foo>{foo:'bar'});

请注意,这与现有的构造Partial相似,例如Partial<T>,希望上述内容能够自解释。我不确定Subset<>Superset<>是否都有意义,但其中一个应该是有意义的。

fae0ux8s

fae0ux8s1#

精确类型 #12936

camsedfj

camsedfj3#

再次审视这个问题,我认为 Subset<T>Superset<T> 都有意义。示例:

  1. const v = {foo:'bar'};
  2. const vprime = Subset<T>v;

Subset<T> 的作用类似于Assert:Assert是 vprime 不能有任何不在 T 中的字段。返回的只包含 v 中的内容,而不是 T 中的内容。
接下来我们有超集:

  1. const v = {foo:'bar', zoom:'zam'};
  2. const vprime = Superset<T>v;

超集的作用类似于Assert:它Assert vprime 包含 T 中的所有字段。从Assert中返回 v 的类型,而不是 T

mqkwyuun

mqkwyuun4#

这个能用吗?

  1. type Subset<L, R extends L> = L
  2. type Superset<L extends R, R> = L
  3. interface T {
  4. foo: 'foo';
  5. bar: 'bar';
  6. }
  7. const v: { foo: 'foo' } = {
  8. foo: 'foo'
  9. };
  10. const v2: { foo: 'foo'; bar: 'bar', baz: 'baz' } = {
  11. foo: 'foo', bar: 'bar', baz: 'baz'
  12. };
  13. const vprime1: Subset<typeof v, T> = v; // ok
  14. const vprime2: Superset<typeof v, T> = v; // notok
  15. const vprime2_1: Subset<typeof v2, T> = v2; // notok
  16. const vprime2_2: Superset<typeof v2, T> = v2; // ok
展开查看全部
4nkexdtk

4nkexdtk5#

@jack-williams 可能,除了我正在寻找使用它与一个匿名对象,如下所示:

  1. type T = ...
  2. doMyThang((err, val) => {
  3. res.json(<T>val.x);
  4. });

它需要是一个Assert,就像那样...也就是说,这样做有点让我失望:

  1. type T = ...
  2. doMyThang((err, val) => {
  3. const x : T = val.x; /// << superfluous code that I don't want to write or see
  4. res.json(x);
  5. });

我认为使用匿名对象是更高层次的目标。

展开查看全部

相关问题