打字稿枚举比较'in'有效,但不能'==='



我正试图使用Enum从rxjs可观察到的对象中获得安全的事件输出。以下是完整的代码示例:

// Enum
export enum Key {
ArrowUp = "ArrowUp",
ArrowDown = "ArrowDown",
ArrowLeft = "ArrowLeft",
ArrowRight = "ArrowRight",
W = "w",
A = "a",
S = "s",
D = "d",
One = "1",
Two = "2",
}
// Observable
export const useKeyboardEvent = () => {
const $keyboardEvent: Observable<Key> = fromEvent<KeyboardEvent>(
document,
"keydown"
).pipe(
filter((event: KeyboardEvent) => {
return !!Object.values(Key).find((v) => v === event.key);
}),
map(
(event: KeyboardEvent) =>
Object.keys(Key)[
(Object.values(Key) as string[]).indexOf(event.key)
] as Key
),
distinctUntilChanged()
);
return $keyboardEvent;
};
// Subscription
React.useEffect(() => {
const keyboardEventSub = $keyboardEvent.subscribe(setColor);
return () => {
keyboardEventSub.unsubscribe();
};
}, [$keyboardEvent, setColor]);
// handler
const color = React.useRef<string>("black");
const setColor = React.useCallback((key: Key) => {
if (key === Key.One) {
color.current = "black";
} else if (key === Key.Two) {
color.current = "red";
}
}, []);

当我注销不同的比较时,我看到的结果是:

key === Key.One false 
key in Key true

我的问题:如何比较才能使key === Key.One成功?为什么这种比较失败了,而in成功了?

枚举在TypeScript中很有趣。它们基本上是键和值之间的映射。因此,当你传递key时,你传递的是字符串"One",但当你得到Key.One进行比较时,你得到的是字符串"1"。所以,"One" === "1"返回false,您就被卡住了。

执行key in Key时,它会在Key枚举中查找属性名One,并找到它,因此返回true。当然,这只是告诉您keyKey枚举的一个成员,所以不是很有用。

顺便说一句,属性名称被称为";键";,正如你可能知道的,但为了清楚起见,我放弃了双关语。但这很难做到。

您可以做的是确保将key的类型指定为Key,以便TypeScript在被要求时正确地将值映射到值。正如您所发现的,这样做的一种方法是将映射更改为:

Object.values(Key).find((v) => v === event.key) as Key

最新更新