我使用名义类型/品牌来表示通过 React 的 useMemo 传递的值。
type Memoed<T> = T extends Primitive ? T
: T extends { __MEMOED: true } ? T
: T & { __MEMOED: true };
declare function useMemo<T extends any>(
callback: () => T,
deps: ReadonlyArray<Primitive | Memoed<object>>,
): Memoed<T>;
这在大多数情况下都可以正常工作。但是,当我使用 Object.keys
、Object.values
或传播对象时,这会导致问题。例如。如果我传播一个记忆对象来创建一个新对象,则新对象不会被记忆。但是,它仍然具有 __IS_USE_MEMO
属性,因此 Typescript 将允许它作为 useMemo
的参数。例如:
const objA = useMemo(() => ({ a: 1 }), []);
const objB = { ...objA };
const objC = useMemo(() => objB, [objB]); // Should be error
如果我可以将 __MEMOED
标记为不可枚举,那么这个问题应该会消失。这可能吗?
答案 0 :(得分:2)
似乎唯一的方法是将带有“memoed”标记的类定义为方法(技术上不需要是方法,但用其他任何东西扩展原型会更复杂)。< /p>
这似乎确实有效(而不是您对 __MEMOED
的定义):
declare class __MEMOED {
memoed(): true
}
type Memoed<T> = T extends Primitive ? T
: T extends __MEMOED ? T
: T & __MEMOED
尽管……如果您记住任何不是基本对象的内容,事情就会变得非常奇怪,此时您确实需要扩展基类。