You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中确保缓存删除时键与对应值的类型匹配?

问题描述

需要实现缓存删除函数cacheDel,要求当传入的value类型与指定key在对应元素类型中的类型不匹配时,TypeScript能抛出类型错误。当前实现中,value的类型被定义为T[keyof T],这会允许传入任何属于T属性的类型,无法约束到当前选中的key对应的类型。

示例错误调用:

type ItemA = { id: number; name: string; isPrivate: boolean };
// 预期触发错误:`id`应为number类型,却传入字符串
cacheDel<ItemA>(cacheStore, "arrayOfItemA", "id", "not-a-number");

完整初始代码:

type CacheStore = Record<string, unknown[]>;

const cacheGet = <T>(store: CacheStore, hash: keyof CacheStore) => {
  return store[hash] as T[];
};

const cachePut = <T>(store: CacheStore, hash: keyof CacheStore, array: T[]) => {
  return (store[hash] = array);
};

const cacheDel = <T>(store: CacheStore, hash: keyof CacheStore, key: keyof T, value: T[keyof T]) => {
  const data = cacheGet<T>(store, hash);
  const updatedData = [...data.filter((item) => item[key] !== value)];
  cachePut(store, hash, updatedData);
};

type ItemA = { id: number; name: string; isPrivate: boolean };
type ItemB = { token: string; label: string; counter: number };

const cacheStore = {
  arrayOfItemA: [
    { id: 1, name: "item A", isPrivate: true },
    { id: 2, name: "item AA", isPrivate: false },
  ],
  arrayOfItemB: [
    { token: "aaaaa", label: "hello" },
    { token: "bbbbb", label: "bye" },
  ],
};
cacheDel<ItemA>(cacheStore, "arrayOfItemA", "id", "not-a-number"); // 应触发错误
cacheDel<ItemB>(cacheStore, "arrayOfItemB", "token", 1); // 应触发错误
解决方案

核心问题是原cacheDel的泛型仅定义了T,没有将key和value的类型绑定。我们需要新增泛型参数K来约束key的具体类型,同时让value的类型严格对应T[K],实现类型匹配检查。

修改后的cacheDel函数:

const cacheDel = <T, K extends keyof T>(
  store: CacheStore,
  hash: keyof CacheStore,
  key: K,
  value: T[K]
) => {
  const data = cacheGet<T>(store, hash);
  const updatedData = [...data.filter((item) => item[key] !== value)];
  cachePut(store, hash, updatedData);
};

改动说明

  • 新增泛型参数K extends keyof T:明确key必须是T的属性名,同时保留key的具体类型信息。
  • 将value的类型从T[keyof T]改为T[K]:让value的类型严格匹配选中key在T中的属性类型,传入不匹配类型时TypeScript会直接抛出错误。

修改后,之前的错误调用会被正确识别:

  • cacheDel<ItemA>(cacheStore, "arrayOfItemA", "id", "not-a-number"):提示"not-a-number"无法赋值给number类型。
  • cacheDel<ItemB>(cacheStore, "arrayOfItemB", "token", 1):提示1无法赋值给string类型。

内容的提问来源于stack exchange,提问作者Alex Conrad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 11:01:02