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

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

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

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

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

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

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

camsedfj

camsedfj3#

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

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

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

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

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

mqkwyuun

mqkwyuun4#

这个能用吗?

type Subset<L, R extends L> = L

type Superset<L extends R, R> = L

interface T {
    foo: 'foo';
    bar: 'bar';
}

const v: { foo: 'foo' } = {
    foo: 'foo'
};

const v2: { foo: 'foo'; bar: 'bar', baz: 'baz' } = {
    foo: 'foo', bar: 'bar', baz: 'baz'
};

const vprime1: Subset<typeof v, T> = v; // ok
const vprime2: Superset<typeof v, T> = v; // notok

const vprime2_1: Subset<typeof v2, T> = v2; // notok
const vprime2_2: Superset<typeof v2, T> = v2; // ok
4nkexdtk

4nkexdtk5#

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

type T = ...

doMyThang((err, val) => {
    res.json(<T>val.x);
});

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

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

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

相关问题