具有索引签名的接口的可选链接

Optional chaining for interfaces that have an index signature

我定义了两个接口。第一个有一个可选字段,第二个有一个索引签名:

interface A {
  foo?: { bar: number };
}

interface B {
  [s: string]: { bar: number };
}

为什么当我使用可选链接访问 属性 时,第一个接口给我类型 number | undefined 的结果,而第二个接口只给出类型 number?

const a: A = {};
const aa = a.foo?.bar;
// const aa: number | undefined

const b: B = {};
const bb = b.foo?.bar;
// const bb: number

因为 B 由 [s: string] 索引,它相信任何有效的字符串键都会导致 { bar: number } 的值被访问。所以,

const b: B = {};
const bb = b.foo?.bar;

它认为 foo 属性 将永远存在 - 它永远不会失败并通过可选链接变成 undefined

与A相比:

interface A {
  foo?: { bar: number };
}

由于 foo 属性 在这里是可选的,它 不是 肯定存在(对 Typescript),所以 ?. 可能会导致没有 属性 被找到并且 undefined 是结果。

您可以通过在对象值类型中交替使用 undefined 来明确表示并非 B 上的所有属性都必须具有 bar 对象:

interface B {
  [s: string]: { bar: number } | undefined;
}

导致 bb 被键入为 number | undefined