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

如何定义限制额外未声明键的TypeScript扩展接口?

如何定义限制额外键的类型/接口,同时兼容父类型?

我有一个定义路由的标准接口:

interface Routes {
  [key: string]: string | Routes;
}

我想为每个模块定义子类型,比如:

interface GeoRoutes extends Routes {
    country: {
        list: string;
    };
}

目前代码能正常运行,但我希望禁止GeoRoutes对象包含未定义的额外键。比如下面的声明现在能编译通过,但我想让它编译失败:

const apiRoutes: GeoRoutes = {
    foo: 'bar',
    country: {
        list: '/countries',
    },
};

核心需求是:子类型既要能在处理Routes的方法中使用(比如function addRoute(routes: Routes) { ... }),又要严格限制只能包含指定的键。


因为Routes带有字符串索引签名,直接继承它的接口会自动允许任意字符串键——这是TypeScript的设计规则:只要接口继承了带索引签名的类型,就会继承这个“允许任意键”的特性。要实现严格键约束,你可以用以下几种方法:

方案一:交叉类型+严格定义

先写好模块专属的严格路由类型,再和Routes做交叉,这样既保证类型能传给Routes参数,又能限制额外键:

type StrictGeoRoutes = {
    country: {
        list: string;
    };
} & Routes;

// 编译报错:对象文字只能指定已知属性,'foo' 不在类型 'StrictGeoRoutes' 中
const apiRoutes: StrictGeoRoutes = {
    foo: 'bar',
    country: {
        list: '/countries',
    },
};

// 正常编译:StrictGeoRoutes 兼容 Routes 类型
function addRoute(routes: Routes) {}
addRoute(apiRoutes);

方案二:用satisfies关键字(TypeScript 4.9及以上)

如果不想改类型结构,可以用satisfies确保对象符合严格的模块路由结构,再通过类型断言兼容Routes:

type GeoRoutesStrict = {
    country: {
        list: string;
    };
};

// 编译报错:对象文字只能指定已知属性,'foo' 不在类型 'GeoRoutesStrict' 中
const apiRoutes = {
    foo: 'bar',
    country: {
        list: '/countries',
    },
} satisfies GeoRoutesStrict as Routes;

// 正常编译
addRoute(apiRoutes);

方案三:工具类型移除索引签名

如果必须用接口继承,可以写个工具类型去掉父接口的索引签名,再合并:

type RemoveIndexSignature<T> = {
    [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]
};

interface GeoRoutesStrict {
    country: {
        list: string;
    };
}

type GeoRoutes = GeoRoutesStrict & Routes;

// 编译报错:'foo' 不在类型 'GeoRoutes' 中
const apiRoutes: GeoRoutes = {
    foo: 'bar',
    country: {
        list: '/countries',
    },
};

这些方案的核心都是把“严格键约束”和“父类型兼容性”分开处理,避开继承索引签名带来的宽松限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:20:40