通过将常量导出为对象来松开类型信息

问题描述

以下方法(扩展对象)提示错误

types.ts

interface SetAppDataAction {
    type: typeof SET_APP_DATA // need to be exactly the string! not just any string
}

const SET_APP_DATA = "SET_APP_DATA"
export default { SET_APP_DATA }

action.ts

import types from "./types";

const setAppData = (appData: IAppDataState): SetAppDataAction => {
    return {
        type: types.SET_APP_DATA,// Typescript error: TS2322: Type '{ SET_APP_DATA: string; }' is not assignable to type '"SET_APP_DATA"'
        payload: appData
    }
}

有人可以解释一下这里发生了什么吗?通过将类型信息包装在对象中而丢失类型信息吗? (之前输入:完全是“ SET_APP_DATA”,之后仅是字符串?)

enter image description here

解决方法

是的,这很正常。将常量放在对象中会使(mutable!)对象属性具有较少特定的类型。您可以使用const assertions来防止这种情况:

export default { SET_APP_DATA } as const;

但是,我建议您根本不要默认导出对象!而是利用名称导出:

// types.ts
export const SET_APP_DATA = "SET_APP_DATA";
// action.ts
import * as types from "./types";

const setAppData = (appData: IAppDataState): SetAppDataAction => {
    return {
        type: types.SET_APP_DATA,payload: appData
    }
}
,

另一种解决方案是使用显式类型而不是依赖类型推断。

interface SetAppDataAction {
    type: typeof SET_APP_DATA // need to be exactly the string! not just any string
}

const SET_APP_DATA = "SET_APP_DATA"
const objectToExport: { SET_APP_DATA: typeof SET_APP_DATA } =  { SET_APP_DATA }
export default objectToExport