[英]react typescript: use "Object.freeze" (enum) as type
我有这个“枚举”:
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);
是否有可能以某种方式表明 state 的类型是 AuthEnum?
这个useState<AuthEnum>(AuthEnum.PENDING)
不起作用,因为AuthEnum
是一个运行时值,它被用作一种类型。 仅当AuthEnum
是枚举时才允许以这种方式使用它。
这个const [isAuthenticated, setIsAuthenticated] = useState<typeof AuthEnum>(AuthEnum.PENDING);
不起作用,因为typeof AuthEnum
是 object 并且您传递的是数字AuthEnum.PENDING
。
事实上,您只想使用AuthEnum
的值。 为了做到这一点,首先你应该使用as const
断言来缩小 object 值的类型。
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
实用程序类型返回所有 object 值的联合。
有“as const”的原因是什么?
没有as const
AuthEnum
就变成了:
Readonly<{
AUTHENTICATED: number;
UNAUTHENTICATED: number;
PENDING: number;
}>
而使用as const
- 所有 object 值都严格缩小:
Readonly<{
readonly AUTHENTICATED: 1;
readonly UNAUTHENTICATED: 2;
readonly PENDING: 3;
}>
as const
使您的 object 不仅不可变,而且还缩小了所有值类型。
这就是为什么问题的作者使用 immutable object 而不是enum
的原因。 既然您只有 3 个属性: 1, 2, 3
为什么您允许将setIsAuthenticated
function 与任何其他 arguments 一起调用? 很明显,调用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
是一种更安全的方法的文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.