是否可以将常量的值用作另一个的文字类型? 我的用例是Redux特有的,但也可以在其他地方使用。
我的行动定义如下:
import { APP_NAME } from 'js/commons/constants/ReduxAppName';
const MODAL_OPEN = `${APP_NAME}/MODAL/OPEN`;
const MODAL_CLOSE = `${APP_NAME}/MODAL/CLOSE`;
export const types = {
MODAL_OPEN,
MODAL_CLOSE,
};
现在在我的reducer中我导入了这些类型:
import { types } from './modalTypes';
import { BaseActionI } from 'js/redux/interfaces/ReduxInterfaces';
const { MODAL_OPEN, MODAL_CLOSE } = types;
我想让我的减速机类型安全。动作的有效负载可以是数字(用于结束)或JSX.Element(在打开时)。
所以我想写这样的东西:
interface ModalCloseActionI extends BaseActionI {
type: MODAL_OPEN,
payload: number,
}
interface ModalOpenActionI extends BaseActionI {
type: MODAL_CLOSE
payload: JSX.Element
}
那么我可以说我的reducer需要一个ModalOpenActionI | ModalCloseActionI
export const modalReducer = (state = Immutable.List<JSX.Element>(), action: ModalOpenActionI | ModalCloseActionI) => {
const { type, payload } = action;
switch (type) {
case MODAL_OPEN: {
return state.push(payload);
}
case MODAL_CLOSE: {
return state.remove(payload as number);
}
default: {
return state;
}
}
}
那么我的switch案例是类型安全的,编译器可以假设在MODAL_OPEN
内有效负载实际上是JSX.Element
有没有办法在不写重复代码的情况下完成此任务?
答案 0 :(得分:1)
您正在尝试将值用作类型,但不起作用 好消息是您可以使用相同的名称定义类型:
const { MODAL_OPEN, MODAL_CLOSE } = types;
type MODAL_OPEN = string;
type MODAL_CLOSE = string;
这应该有效。
如果您希望类型为单个字符串文字,请执行以下操作:
interface ModalCloseActionI extends BaseActionI {
type: "close",
payload: number,
}
interface ModalOpenActionI extends BaseActionI {
type: "open"
payload: JSX.Element
}
如果字符串值不是静态的,那么你就无法做到这一点,就像你创建它们一样:
const MODAL_OPEN = `${APP_NAME}/MODAL/OPEN`;
即使使用静态字符串文字,您仍需要将其声明为类型:
const { MODAL_OPEN, MODAL_CLOSE } = types;
type MODAL_OPEN = "MODAL/OPEN";
type MODAL_CLOSE = "MODAL/CLOSE";
这很烦人,因为你需要重新声明每个变量,并且你在字符串值中有重复(这可能会导致错误)。
您可以导出命名空间而不是const:
export namespace types {
export const MODAL_OPEN = `MODAL/OPEN`;
export type MODAL_OPEN = "MODAL/OPEN";
export const MODAL_CLOSE = `MODAL/CLOSE`;
export type MODAL_CLOSE = "MODAL/CLOSE";
}
然后定义在同一个地方,但你需要像这样使用它:
interface ModalCloseActionI {
type: types.MODAL_OPEN,
payload: number,
}
interface ModalOpenActionI {
type: types.MODAL_CLOSE
payload: JSX.Element
}