TypeScript如何定义键值类型匹配指定接口的Map?
正确实现键值类型匹配的Map类型定义
你之前的写法错误在于把MyMap定义成了泛型类型,导致每次使用都必须指定单一的键类型,无法容纳Data中所有合法的键值对。以下是两种正确的实现方式:
方式一:直接使用约束后的Map类型
这是最简单的实现方式,TypeScript会在调用get/set时自动校验键值类型的匹配性:
type Article = { id: number }; type Comment = { text: string }; type Data = { articles: Article[], comments: Comment[] }; // 正确的类型定义 type MyMap = Map<keyof Data, Data[keyof Data]>; // 使用示例 const map: MyMap = new Map(); map.set('articles', [{ id: 1 }]); // 合法,值类型匹配articles的定义 map.set('comments', [{ text: 'hello' }]); // 合法,值类型匹配comments的定义 map.set('articles', [{ text: 'invalid' }]); // 报错:类型不匹配 const articles = map.get('articles'); // 类型自动推断为 Article[] | undefined const comments = map.get('comments'); // 类型自动推断为 Comment[] | undefined
方式二:自定义严格约束的Map类型
如果需要更明确的方法类型约束,可以通过合并自定义方法和原生Map类型来实现:
type StrictMyMap = { get<K extends keyof Data>(key: K): Data[K] | undefined; set<K extends keyof Data>(key: K, value: Data[K]): this; } & Omit<Map<keyof Data, Data[keyof Data]>, 'get' | 'set'>; // 使用示例 const strictMap: StrictMyMap = new Map(); strictMap.set('articles', [{ id: 2 }]); const strictArticles = strictMap.get('articles'); // 明确为 Article[] | undefined
为什么原写法无效?
你写的type MyMap = <K extends keyof Data>Map<K, Data[K]>是泛型类型别名,它要求使用者必须指定具体的键类型(比如MyMap<'articles'>),这样的Map只能存储单一类型的键值对,无法同时容纳Data中多个不同的键值条目,不符合你的需求。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

