打字稿:将对象属性标记为不可枚举?

时间:2021-04-28 06:43:31

标签: javascript typescript

我使用名义类型/品牌来表示通过 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.keysObject.values 或传播对象时,这会导致问题。例如。如果我传播一个记忆对象来创建一个新对象,则新对象不会被记忆。但是,它仍然具有 __IS_USE_MEMO 属性,因此 Typescript 将允许它作为 useMemo 的参数。例如:

const objA = useMemo(() => ({ a: 1 }), []);
const objB = { ...objA };
const objC = useMemo(() => objB, [objB]); // Should be error

TS Playground

如果我可以将 __MEMOED 标记为不可枚举,那么这个问题应该会消失。这可能吗?

1 个答案:

答案 0 :(得分:2)

似乎唯一的方法是将带有“memoed”标记的类定义为方法(技术上不需要是方法,但用其他任何东西扩展原型会更复杂)。< /p>

这似乎确实有效(而不是您对 __MEMOED 的定义):

declare class __MEMOED {
  memoed(): true
}

type Memoed<T> = T extends Primitive ? T
  : T extends __MEMOED ? T
  : T & __MEMOED

尽管……如果您记住任何不是基本对象的内容,事情就会变得非常奇怪,此时您确实需要扩展基类。

相关问题