[英]Switch with specific type in TypeScript not working
I am trying to implement constants in an interface, but why does it give an error while accessing data
in the switch case?我正在尝试在接口中实现常量,但为什么在 switch case 中访问
data
时会出错?
If I use just string
in interface
instead of constants APP_STATUS
then it works fine.如果我在
interface
中只使用string
而不是常量APP_STATUS
那么它就可以正常工作。
Example:例子:
// Gives an error
interface InconsistenciesData {
type: typeof APP_STATUS.INCONSISTENCIES;
data: Inconsistency[];
}
// Works fine
interface InconsistenciesData {
type: 'INCONSISTENCIES';
data: Inconsistency[];
}
Below are my code snippets.以下是我的代码片段。
export const APP_STATUS = {
CONFIRMED: 'CONFIRMED',
INCONSISTENCIES: 'INCONSISTENCIES',
SUCCESS: 'SUCCESS',
ERROR: 'ERROR',
LOADING: 'LOADING',
OK: 'OK'
}
interface InconsistenciesLoading {
type: typeof APP_STATUS.LOADING;
}
interface InconsistenciesError {
type: typeof APP_STATUS.ERROR;
}
interface InconsistenciesSuccess {
type: typeof APP_STATUS.SUCCESS;
}
interface InconsistenciesData {
type: typeof APP_STATUS.INCONSISTENCIES;
data: Inconsistency[];
}
export type ViewState = InconsistenciesData | InconsistenciesSuccess | InconsistenciesLoading | InconsistenciesError;
const [viewState, setViewState] = useState<ViewState>({type: APP_STATUS.LOADING})
const renderPageContent = () => {
switch (viewState.type) {
case APP_STATUS.INCONSISTENCIES:
return <InconsistenciesTable inconsistencies={viewState.data} /> //Error: Property 'data' does not exist on type 'ViewState'. Property 'data' does not exist on type 'InconsistenciesSuccess'.
case APP_STATUS.ERROR:
return <Forbidden />
case APP_STATUS.SUCCESS:
return <ThankYouContent />
case APP_STATUS.LOADING:
return <Loading />
}
}
Just replace your object with an enum, that's what they're for:只需用枚举替换您的对象,这就是它们的用途:
export enum APP_STATUS {
CONFIRMED,
INCONSISTENCIES,
SUCCESS,
ERROR,
LOADING,
OK,
}
export interface Inconsistency {};
export interface InconsistenciesLoading {
type: APP_STATUS.LOADING;
}
export interface InconsistenciesError {
type: APP_STATUS.ERROR;
}
export interface InconsistenciesSuccess {
type: APP_STATUS.SUCCESS;
}
export interface InconsistenciesData {
type: APP_STATUS.INCONSISTENCIES;
data: Inconsistency[];
}
type ViewState = InconsistenciesData | InconsistenciesSuccess | InconsistenciesLoading | InconsistenciesError;
export const component = ({ state }: { state: ViewState }) => {
switch (state.type) {
case APP_STATUS.INCONSISTENCIES:
console.log(state.data); // Look ma, no error!
}
};
Your version fails because unlike an enum your APP_STATE
constant is actually just a regular mutable object: there's no guarantee that your compile-time type will still hold when the switch statement actually takes effect at runtime.您的版本失败是因为与枚举不同,您的
APP_STATE
常量实际上只是一个常规的可变对象:当 switch 语句在运行时实际生效时,无法保证您的编译时类型仍然有效。
export enum APP_STATUS {
CONFIRMED = 'CONFIRMED',
INCONSISTENCIES = 'INCONSISTENCIES',
SUCCESS = 'SUCCESS',
ERROR = 'ERROR',
LOADING = 'LOADING',
OK = 'OK'
}
export interface Inconsistency {};
export interface InconsistenciesLoading {
type: APP_STATUS.LOADING;
}
export interface InconsistenciesError {
type: APP_STATUS.ERROR;
}
export interface InconsistenciesSuccess {
type: APP_STATUS.SUCCESS;
}
export interface InconsistenciesData {
type: APP_STATUS.INCONSISTENCIES;
data: Inconsistency[];
}
type ViewState = InconsistenciesData | InconsistenciesSuccess | InconsistenciesLoading | InconsistenciesError;
I have added String enums, becuase I was using these status in other files also, like:我添加了字符串枚举,因为我也在其他文件中使用了这些状态,例如:
if(response.status === APP_STATUS.SUCCESS) {
//code
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.