Reputation: 2585
The following approach (exporing a object) hints an error:
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
}
}
Can anyone explain me whats going on here? Is it possible that the type information is lost by wrapping it in a object? (type before: exactly "SET_APP_DATA", afterwards only string?)
Upvotes: 1
Views: 737
Reputation: 665121
Yes, this is normal. Putting constants in objects makes the (mutable!) object property have a less specific type. You can prevent this using const assertions:
export default { SET_APP_DATA } as const;
However, I would recommend that you do not default-export an object at all! Rather make use of names exports:
// 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
}
}
Upvotes: 3
Reputation: 851
Another solution would be to use explicit typing instead of relying on type inference.
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
Upvotes: 1