简体   繁体   English

代理对象分配类型错误 TypeScript

[英]Proxied Object Assignment Type Error TypeScript

I have a cache that my app uses and the cache is wrapped in a Proxy that manages the expiration validation.我有一个我的应用程序使用的缓存,并且缓存被包装在一个管理过期验证的代理中。

Here are some of the List definitions from my Lists.d.ts file for reference but I don't think the issue exists here.以下是我的 Lists.d.ts 文件中的一些列表定义以供参考,但我认为这里不存在问题。

interface MetaData {
  Title: string | null;
  FileSystemObjectType: number;
  Id: number;
  // ....
}

// The CreationProps types just define the fields in the object
type DeviceCreationProps = {
  Model: string;
  Manufacturer: string;
  // ...
};

type CommentData = MetaData & CommentCreationProps;
type DeviceData = MetaData & DeviceCreationProps;
type UserData = MetaData & UserCreationProps;

type ListDataMap = {
  Comments: CommentData;
  Devices: DeviceData;
  Users: UserData;
};

type ListName = keyof ListDataMap;

Now in my ListItemCache.ts file I have the following code:现在在我的 ListItemCache.ts 文件中,我有以下代码:

type CacheExpirationMapValue = {
  // [list name] : expiration date object
  [List in ListName]?: Date;
};
const CacheExpirationMap: CacheExpirationMapValue = {};

type RawListItemCacheValue = {
  // [name of list]: array of list items
  [List in ListName]?: ListDataMap[List][];
};
const RawListItemCache: RawListItemCacheValue = {};

const maxAge = 1000 * 60 * 5;

// This is a proxied object that allows us to handle the expirations when fetching cached objects
const ListItemCache = new Proxy(RawListItemCache, {
  set<List extends ListName>(obj, prop: List, value: ListDataMap[List][]) {
    const expires = new Date(Date.now() + maxAge);

    CacheExpirationMap[prop] = expires;

    obj[prop] = value;

    return true;
  },

  get(obj, prop) {
    const item = obj[prop];
    const now = new Date();

    if (item && !!CacheExpirationMap[prop] && CacheExpirationMap[prop] > now) {
      return item;
    }

    return [];
  },
});

export default ListItemCache;

Everything is fine and I don't get any issues in this file, but when I try to set the value of the cache in another file for instance:一切都很好,我在这个文件中没有任何问题,但是当我尝试在另一个文件中设置缓存的值时:

export default function usePopulateCache<List extends ListName>(list: List) {
  const { sp } = useContext(SPContext);
  useEffect(() => {
    sp.web.lists
      .getByTitle(list)
      .items<ListDataMap[List][]>()
      .then((items) => {
        ListItemCache[list] = items;
      });
  }, []);
}

I get the following error in the assignment:我在作业中收到以下错误: 在此处输入图像描述

I'm not sure why this is because the List type that indexes both of them is the same and RawListItemCacheValue[List] should be the same as ListDataMap[List][] according to its type definition.我不确定为什么这是因为索引它们的 List 类型是相同的,并且RawListItemCacheValue[List] ListDataMap[List][]相同。

the problem here is that RawListItemCacheValue[List] is not the same as ListDataMap[List][] , even though it really looks like it is.这里的问题是RawListItemCacheValue[List]ListDataMap[List][]不同,即使它看起来确实如此。

If you check the error you will see whats the difference is in that line: CommentData | DeviceData | UserData is not assignable to type CommentData如果您检查错误,您将看到该行有什么不同: CommentData | DeviceData | UserData is not assignable to type CommentData CommentData | DeviceData | UserData is not assignable to type CommentData CommentData | DeviceData | UserData is not assignable to type CommentData . CommentData | DeviceData | UserData is not assignable to type CommentData

What this means is that when yo do this:这意味着当你这样做时:

type RawListItemCacheValue = {
  // [name of list]: array of list items
  [List in ListName]?: ListDataMap[List][];
};

somehow you are telling tsc this:不知何故,你告诉tsc这个:

type RawListItemCacheValue = {
  [CommentData]?: ListDataMap[CommentData][];
  [DeviceData]?: ListDataMap[DeviceData][];
  {...}
};

So the key and the value are correlated.所以键和值是相关的。

The problem is that when you do ListDataMap[List][] with List being === to keyof ListName , this value can be anyone on ListDataMap .问题是,当您执行ListDataMap[List][]List === to keyof ListName时,此值可以是ListDataMap上的任何人。 So when you do ListItemCache[list] = items;所以当你做ListItemCache[list] = items; you are really doing:你真的在做:

ListItemCache['CommentData' | 'DeviceData' | 'UserData'] = (CommentData | DeviceData | UserData)[]

So tsc complains for that because ListItemCache['CommentData'] = DeviceData would be a possible combination which is wrong.所以tsc对此抱怨,因为ListItemCache['CommentData'] = DeviceData可能是错误的组合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM