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.keys、Object.values 或者在展開物件時,會造成問題。例如,如果我展開一個被記憶化的物件以創建一個新物件,新的物件並沒有被記憶化。然而,它仍然會有 __IS_USE_MEMO 屬性,因此 Typescript 會允許它作為 useMemo 的參數。例如:
const objA = useMemo(() => ({ a: 1 }), []);
const objB = { ...objA };
const objC = useMemo(() => objB, [objB]); // Should be error
TS 遊樂場
如果我可以將 __MEMOED 設為不可列舉,那麼這個問題應該就會消失。這可能嗎?
答案#1
看起來唯一的方法是定義一個類,將你的「memoed」標記作為方法(技術上不必是方法,但用其他方式擴展原型會更複雜)。
這似乎真的有效(而不是你對 __MEMOED 的定義):
declare class __MEMOED {
memoed(): true
}
type Memoed<T> = T extends Primitive ? T
: T extends __MEMOED ? T
: T & __MEMOED
雖然……如果你備忘錄任何不是基本對象的東西,情況會變得非常奇怪,到了那時你真的需要擴展基類。
