如何在TypeScript类型层面确保Subset仅含main的键?含例外处理
一、约束Subset仅包含main的已有键
要在类型层面限制Subset的键只能来自main的已有键,可以通过提取main的键类型,再结合类型约束实现:
步骤1:提取main的键类型
从const断言的main对象中提取所有键的类型:
const main = { a: {name: "A"}, b: {name: "The B"}, c: {name: "The Sea"}, // ... } as const; // 提取main的所有键类型 type MainKeys = keyof typeof main;
步骤2:定义约束类型,禁止额外键
创建一个通用类型,确保传入的类型中,所有不在MainKeys里的键都会被标记为never(一旦定义这类键就会触发类型报错):
// 约束类型:仅允许MainKeys内的键,额外键类型为never type RestrictToMainKeys<T> = T & Record<Exclude<keyof T, MainKeys>, never>;
步骤3:应用约束到Subset
将Subset定义为符合该约束的类型,这样如果意外添加uniqueKey这类不在main中的键,TypeScript会直接报错:
export interface Subset extends RestrictToMainKeys<{ b?: string, c?: string[], // 若添加 uniqueKey?: number,会触发类型错误:类型“number”不能赋值给类型“never” }> {}
也可以用类型别名的方式实现,写法更简洁:
export type Subset = RestrictToMainKeys<{ b?: string, c?: string[], }>;
二、处理少数例外键
如果需要允许个别不在main中的例外键(比如uniqueKey),只需修改约束类型,将例外键加入允许列表即可:
步骤1:定义例外键类型
// 声明允许的例外键 type ExceptionKeys = 'uniqueKey' | 'anotherException';
步骤2:更新约束类型,包含例外键
调整约束逻辑,让MainKeys和ExceptionKeys内的键都被允许,其他键仍被限制:
type RestrictToMainKeysWithExceptions<T> = T & Record<Exclude<keyof T, MainKeys | ExceptionKeys>, never>;
步骤3:应用带例外的约束
此时可以安全添加例外键,不会触发类型错误:
export interface Subset extends RestrictToMainKeysWithExceptions<{ b?: string, c?: string[], uniqueKey?: number, // 例外键,不会报错 }> {}
内容的提问来源于stack exchange,提问作者user3064538
相关产品推荐
相关产品推荐

