接口不能扩展条件类型中的映射类型

Interface cannot extend mapped type in conditional type

在调试我的程序时,我注意到以下示例会产生编译错误 (playground)。

type Foo = {key: string};
interface Bar {key: string};

type Baz = Foo extends Record<string, unknown>? any: never;
type Qux = Bar extends Record<string, unknown>? any: never;

const baz: Baz = 0;
const qux: Qux = 0; // Type 'number' is not assignable to type 'never'.

似乎接口不能扩展 Record<string, unknown> 而类型可以。我知道 TypeScript 中的类型和接口之间存在一些差异,我怀疑映射类型不能在接口中使用这一事实可能解释了这种行为。我无法完全理解为什么这种地图类型限制会导致 Qux 成为 never,即使是这样。

此外,interface Foobar extends Record<string, unknown> { key: string };是一个有效的接口定义,这让错误更让我困惑。

谁能帮我理解这个错误?

这是因为类型别名具有隐式索引签名,但接口没有。

如果您将索引签名添加到接口 - Qux 将导致 any:

interface Bar { 
    key: string;
    [p: string]: string;
};

Playground

更多信息here

This behavior is currently by design. Because interfaces can be augmented by additional declarations but type aliases can't, it's "safer" (heavy quotes on that one) to infer an implicit index signature for type aliases than for interfaces.