You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何TypeScript对interface报错却不对type报错?

TypeScript中Interface与Type的索引签名兼容性差异问题

同样定义了结构完全一致的FooInterface接口和FooType类型别名,将它们的实例传入要求带有字符串索引签名的函数fn时,FooInterface的实例会抛出类型不兼容错误,而FooType的实例却能正常运行。

代码示例

const fn = (a: { [key: string]: number | string }) => {
  console.log(a)
};

interface FooInterface {
  id: number;
  name: string;
}
type FooType = {
  id: number;
  name: string;
}

const fooInterface: FooInterface = { id: 1, name: 'name' };
const fooType: FooType = { id: 1, name: 'name' };

fn(fooType);
fn(fooInterface); // <-- 此处报错

错误信息

Argument of type 'FooInterface' is not assignable to parameter of type '{ [key: string]: string | number; }'.
Index signature for type 'string' is missing in type 'FooInterface'.

原因分析

类型系统的隐式索引签名规则

函数fn的参数要求是带有string类型索引签名的对象,即所有字符串键对应的属性值必须是number | string类型。

Type别名的特性

FooType是对象字面量的类型别名,TypeScript会隐式判定它符合索引签名要求:

  • 它的所有已知属性类型都匹配number | string;
  • 类型别名是不可扩展的,不会有后续添加不符合索引签名属性的可能,因此TypeScript允许它赋值给带索引签名的类型。

Interface的特性

FooInterface是接口,TypeScript的接口支持声明合并——你可以在代码的其他位置再次扩展这个接口(比如添加age: boolean这样不符合索引签名的属性)。由于无法保证未来不会出现不符合索引签名的属性,TypeScript不会为接口隐式添加索引签名,因此直接传入时会触发类型不兼容错误。

解决方法

  • 给接口显式添加索引签名:
    interface FooInterface {
      [key: string]: number | string;
      id: number;
      name: string;
    }
    
  • 使用类型断言:
    fn(fooInterface as { [key: string]: number | string });
    
  • 将接口转为类型别名:如果不需要接口的扩展特性,可以直接使用type替代interface。

内容的提问来源于stack exchange,提问作者Duannx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:25:15