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

如何用TypeScript断言对象仅包含字符串联合类型的属性?

实现方案

要确保对象仅包含字符串联合类型中定义的属性(可包含子集,禁止额外属性),可以通过以下两种方法实现:

方法1:使用辅助函数(推荐)

利用TypeScript的类型约束,通过辅助函数强制检查对象的键是否完全属于指定联合类型:

type SupportedChains = 'eth_mainnet' | 'eth_testnet';
// 定义允许的基础结构:联合类型中的键可选
type BaseFixtures = { [chain in SupportedChains]?: any };

// 辅助函数,约束传入对象只能包含SupportedChains中的键
const createFixtures = <T extends BaseFixtures & Record<Exclude<keyof T, SupportedChains>, never>>(obj: T) => obj;

// 合法示例:仅包含允许的属性
const fixtures = createFixtures({
    eth_testnet: {
        // ...
    },
});

// 非法示例:包含额外属性会触发报错
const invalidFixtures = createFixtures({
    eth_testnet: { /* ... */ },
    bsc_mainnet: { /* ... */ }, // TypeScript会提示该属性不允许
});

原理

Record<Exclude<keyof T, SupportedChains>, never> 会对超出联合类型的键进行约束:如果对象存在额外键,这些键的类型会被设为never,而对象属性无法赋值为never类型,从而触发错误。

方法2:使用严格类型断言

通过结合可选映射类型和never类型的索引签名,禁止额外属性:

type SupportedChains = 'eth_mainnet' | 'eth_testnet';
// 严格类型:允许联合类型中的键(可选),禁止任何额外字符串键
type StrictFixtures = {
    [chain in SupportedChains]?: any;
} & {
    [key: string]: never;
};

// 合法示例:仅包含允许的属性
const fixtures = {
    eth_testnet: {
        // ...
    },
} as StrictFixtures;

// 非法示例:包含额外属性会触发断言报错
const invalidFixtures = {
    eth_testnet: { /* ... */ },
    bsc_mainnet: { /* ... */ },
} as StrictFixtures;

原理

{ [key: string]: never } 会限制所有未在联合类型中定义的字符串键的值类型为never,一旦对象存在此类键,TypeScript会因类型不兼容报错。

关于你之前的尝试说明

  1. 使用{ [chain: supportedChain]: any }报错:索引签名的参数类型只能是string、number、symbol,不能是字面量联合类型,因此TypeScript提示使用映射类型替代。
  2. 使用{ [chain in supportedChain]: any }无法阻止多余属性:该映射类型默认要求所有联合类型的键必须存在(必填),且TypeScript的结构类型系统会忽略对象的额外属性(除非是直接赋值对象字面量的场景),同时你需要将其改为可选类型(添加?)才能允许仅包含子集属性,再结合额外约束才能禁止多余键。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 23:02:53