为什么属性上可能存在TypeScript错误,而只接受确实存在的值?

为什么属性上可能存在TypeScript错误,而只接受确实存在的值?,typescript,Typescript,请参见以下示例: const a = { a: 1, b: 1 }; const b = { b: 1, c: 1 }; const all = { a, b }; type Keys = "a" | "b" Object.keys(all).map((key) => { const value = all[(key as Keys)]; const { a, b, c } = value; return { ...

请参见以下示例:

const a = {
    a: 1,
    b: 1
};

const b = {
    b: 1,
    c: 1
};

const all = {
    a, b
};

type Keys = "a" | "b"

Object.keys(all).map((key) => {
    const value = all[(key as Keys)];
    const { a, b, c } = value;

    return { ...{ a, b, c } };
})
对于
a
c
它抛出错误,因为它们并不存在于所有可能的情况中

不应该:

{
    a: number;
    b: number;
} | {
    b: number;
    c: number;
}
实际上是指:

{
  a?: number;
  b: number;
  c?: number;
}
?


链接:

不,这两个词的意思不可能相同,但它们有一些交叉点。考虑

type A = {a: string} | {b: string}
不同之处在于
A
仅允许在具有键
A
或键
b
的对象上,此类型的有效对象不能同时具有键或没有键。第二个
B
是更宽的类型,它允许所有类型
A
都允许加
{A,B}
甚至
{}
。我们可以在类型层面上证明这两种类型之间的关系

type AIsSubTypeB = A extends B ? true : false; // true
type BIsSubTypeA = B extends A ? true : false; // false
上面的意思是,在每种情况下都需要类型
B
,可以使用类型
A
,因为类型
A
比类型
B
更严格,换句话说,它是不正确的

为了更清楚地看到差异,我们也可以将第二个写为union,请考虑:

type A = {a: string} | {b: string}
type B = {a: string} | {b: string} | {} | {a: string, b: string}
A
B
之间的交叉点现在是可见的,它正是
{A:string}{B:string}
,它等于type
A
,这也意味着type
A
是type
B
的子集


答案是-不,这两个定义是不同的,我的简化示例适用于问题中的类型。

这在文档中进行了解释:您还想阅读下面关于类型保护的章节。
type A = {a: string} | {b: string}
type B = {a: string} | {b: string} | {} | {a: string, b: string}