TypeScript:如何限制keyof类型为StorageSchema指定键而非任意字符串
解决TypeScript中keyof包含任意字符串的问题
问题背景
你的代码里,StorageSchema继承了带字符串索引签名的StorageType。按照TypeScript的规则,只要接口存在字符串索引签名,keyof该接口的结果就会包含string类型,导致InputType变成string | "username" | "user" | "email" | "totalItems",而你需要InputType仅包含那些显式定义的键。
解决方案
方案1:用satisfies替代继承(推荐,TypeScript 4.9+)
直接移除继承关系,用satisfies运算符确保StorageSchema的结构符合StorageType的要求,这样既不会继承索引签名,又能保证类型合规:
interface StorageType { [key: string]: StorageType | string | number } interface StorageSchema { username: string, user: { name: string, age: number, address?: { street: string, aptNumber: number, }, }, email: string, totalItems: number, } satisfies StorageType; // 验证结构符合StorageType约束 type InputType = keyof StorageSchema; // 结果:"username" | "user" | "email" | "totalItems"
方案2:保留继承,用Exclude过滤string类型
如果必须保留继承关系,可以通过Exclude工具类型把keyof StorageSchema中的string类型过滤掉:
interface StorageType { [key: string]: StorageType | string | number } interface StorageSchema extends StorageType { username: string, user: { name: string, age: number, address?: { street: string, aptNumber: number, }, }, email: string, totalItems: number, }; type InputType = Exclude<keyof StorageSchema, string>; // 仅保留显式定义的键
方案3:重构StorageType为类型约束
如果StorageType只是用来做结构约束而非实例化接口,可以将其改为类型别名,再通过条件类型确保StorageSchema符合约束:
type StorageType = { [key: string]: StorageType | string | number } interface StorageSchema { username: string, user: { name: string, age: number, address?: { street: string, aptNumber: number, }, }, email: string, totalItems: number, } extends StorageType ? StorageSchema : never; type InputType = keyof StorageSchema;
内容的提问来源于stack exchange,提问作者Mainendra
相关产品推荐
相关产品推荐

