简体   繁体   English

在 TypeScript 中使用特定类型切换不起作用

[英]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.以下是我的代码片段。

File types.ts文件类型.ts

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;

My React component我的 React 组件

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!
    }
};

Playground 操场

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM