如何实现TypeScript泛型约束,强制类型所有键以指定前缀开头?
强制嵌套字段所有键以特定前缀开头的TypeScript类型约束
你当前的Container类型约束之所以无法拦截InvalidType,是因为Record<Prefix, any>这种索引签名仅要求对象包含符合前缀的键,但允许额外的非前缀键存在。要实现「所有键必须以key_开头」的强约束,需要确保传入类型的每一个键都属于指定的前缀模式。
核心解决方案
直接约束泛型参数的所有键都匹配Prefix类型,最简洁的实现方式如下:
type Prefix = `key_${string}`; // 仅允许所有键都符合Prefix格式的类型传入 type Container<T extends keyof T extends Prefix ? T : never> = { data: T; };
验证效果
用你的示例类型测试:
type ValidType = { key_1: string; key_2: number; }; type InvalidType = { key_1: string; blah: number; }; // 符合要求,正常通过类型检查 const container: Container<ValidType> = { data: { key_1: 'hello', key_2: 123, }, }; // 不符合要求,TypeScript会抛出错误:类型"InvalidType"不满足约束条件 const container_2: Container<InvalidType> = { data: { key_1: 'hello', blah: 231, }, };
结合你提到的DataType思路
如果要基于你更新的DataType写法实现,可以通过映射类型将非前缀键的类型标记为never,从而拦截不符合要求的类型:
type Prefix = `key_${string}`; // 映射类型:仅保留符合Prefix的键,非前缀键类型设为never type DataType<T> = { [K in keyof T]: K extends Prefix ? T[K] : never; }; // 约束T必须与DataType<T>结构一致(即无非法键) type Container<T extends DataType<T>> = { data: T; };
这种写法同样能达到预期效果,当T包含非前缀键时,DataType<T>中对应键的类型为never,与原类型不匹配,从而触发类型错误。
内容的提问来源于stack exchange,提问作者Grg
相关产品推荐
相关产品推荐

