TypeScript中如何实现对象键值与内部元素postId的编译时类型校验
实现方案
你最初的写法不生效,是因为TS接口的索引签名无法动态绑定当前遍历的键值,无法直接把键的类型作为泛型传给Comment,使用映射类型+泛型+自动推断的工具函数,就能完美实现你要的编译时校验效果。
第一步:定义基础类型
// 基础评论类型,泛型约束postId的类型 interface Comment<PostId extends string> { id: string; comment: string; postId: PostId } // 映射类型:外层对象的每个键K,对应值是Comment<K>类型的数组 type PostComments<T extends string> = { [K in T]: Comment<K>[] }
第二步:编写辅助构造函数(可选,用于自动推断类型)
如果不想每次手动声明泛型参数,可以写一个简单的工具函数,让TS自动推断传入对象的键类型:
const definePostComments = <T extends string>(comments: PostComments<T>) => comments
用法示例
正确写法(无编译错误)
const comments = definePostComments({ "abc123": [ { id: "xyz098", comment: "a sample comment", postId: "abc123", }, { id: "xyz987", comment: "another sample comment", postId: "abc123", }, ], "bcd123": [ { id: "yxz098", comment: "a new sample comment", postId: "bcd123", }, { id: "yxz987", comment: "another new sample comment", postId: "bcd123", }, ] })
错误写法(编译时报错)
如果数组内postId和外层键不一致,TS会直接抛出类型错误:
const badComments = definePostComments({ "abc123": [ { id: "xyz098", comment: "错误示例", postId: "bcd123", // 此处会报错:类型“"bcd123"”不可分配给类型“"abc123"” } ] })
内容的提问来源于stack exchange,提问作者Raghav Bhardwaj
相关产品推荐
相关产品推荐

