我有这个“列举”:
export const AuthEnum = Object.freeze({
AUTHENTICATED: 1,
UNAUTHENTICATED: 2,
PENDING: 3
})
这会起作用,但有点误导:
const [isAuthenticated, setIsAuthenticated] = useState<number>(AuthEnum.PENDING);
这是我想做的,但不起作用:
const [isAuthenticated, setIsAuthenticated] = useState<AuthEnum>(AuthEnum.PENDING);
这也不起作用:
const [isAuthenticated, setIsAuthenticated] = useState<typeof AuthEnum>(AuthEnum.PENDING);
是否有可能以某种方式表明状态的型别是 AuthEnum?
uj5u.com热心网友回复:
这useState<AuthEnum>(AuthEnum.PENDING)
不起作用,因为AuthEnum
它是一个运行时值并且它被用作一种型别。AuthEnum
只有当它是一个列举时才允许以这种方式使用它。
这const [isAuthenticated, setIsAuthenticated] = useState<typeof AuthEnum>(AuthEnum.PENDING);
不起作用,因为typeof AuthEnum
它是一个物件,而您传递的 AuthEnum.PENDING
是一个数字。
实际上,您只想使用 的值AuthEnum
。为了做到这一点,首先你应该使用as const
断言来缩小物件值的型别。
import React, { useState } from 'react'
const FakeEnum = {
AUTHENTICATED: 1,
UNAUTHENTICATED: 2,
PENDING: 3
} as const // immutability assertion
export const AuthEnum = Object.freeze(FakeEnum)
type Values<T> = T[keyof T]
const App = () => {
const [isAuthenticated, setIsAuthenticated] = useState<Values<typeof AuthEnum>>(AuthEnum.PENDING);
setIsAuthenticated(1) // ok
setIsAuthenticated(2) // ok
setIsAuthenticated(3) // ok
setIsAuthenticated(4) // expected error
return null
}
操场
Values
实用程序型别回传所有??物件值的联合。
没有as const
AuthEnum
变得公正:
Readonly<{
AUTHENTICATED: number;
UNAUTHENTICATED: number;
PENDING: number;
}>
而使用as const
- 所有物件值都严格缩小:
Readonly<{
readonly AUTHENTICATED: 1;
readonly UNAUTHENTICATED: 2;
readonly PENDING: 3;
}>
as const
使您的物件不仅不可变,而且还缩小了所有值型别。
这就是为什么问题的作者使用不可变物件而不是enum
. 既然你只有 3 个属性:1, 2, 3
你为什么允许setIsAuthenticated
使用任何其他自变量呼叫函式?很明显,呼叫setIsAuthenticated(1000)
是无效的,应该突出显示为错误。
请使用常规查看此示例enum
:
enum AuthEnum {
AUTHENTICATED = 1,
UNAUTHENTICATED = 2,
PENDING = 3
}
const App = () => {
const [isAuthenticated, setIsAuthenticated] = useState<AuthEnum>(AuthEnum.PENDING);
setIsAuthenticated(100) // no error, but should be
return null
}
没有错误,但我们会期待。这是因为没有推断出 enum 的值。
你可以查看我关于使用enums
是一种更安全的方式的文章。
0 评论