在下面的代码中,在reduced中指定了代码操作类型(操作为SuccessedAction(,并且一切正常,但如果我删除(作为Successedaction(,我会收到一个错误"类型'SuccessedAction|FailedAction'上不存在有效负载">
现在,如果我用--替换常量
type_SUCCEEDE:'type_SUCceEDE',type_FAILED:'type_FAILED',并像使用type_FAIED和type_SUCCE EDE'一样使用它们,而不是使用类型。失败,键入。成功的话,它不用打字就能工作。
因此,在下面的代码中,我认为typeof不适用于我的操作,因此我必须在减速器中进行typecast。想知道同样的确切原因。如果你知道原因,请帮忙,并在这里帮我找出下面代码中的错误。
谢谢。
//constants
export const type = {
SUCCEEDED: 'type_SUCCEEDED',
FAILED: 'type_FAILED'
};
export interface SucceededAction {
readonly type: typeof type.SUCCEEDED;
readonly payload: string;
}
export interface FailedAction {
readonly type: typeof type.FAILED;
}
//actions
export const Succeeded = (payload: string): SucceededAction => ({
type: type.SUCCEEDED,
payload,
});
export const Failed = (): FailedAction => ({
type: type.FAILED,
});
//reducer
export const myReducer = (
state: string = '',
action:
| SucceededAction
| FailedAction,
): string => {
switch (action.type) {
case type.SUCCEEDED:
return (action as SucceededAction) //type specified
.payload;
case type.FAILED:
return state;
default:
return state;
}
};
现在TypeScript将type.SUCCEEDED
和type.FAILED
都视为string
。这意味着你的行动SucceededAction | FailedAction
就是{ readonly type: string; readonly payload: string; } | { readonly type: string; }
。
类型名称必须是字符串文字类型才能区分并集。这可以通过两种方式实现:
1( 枚举
您可以将type
变量设置为enum
:
export enum type {
SUCCEEDED = 'type_SUCCEEDED',
FAILED = 'type_FAILED'
};
TypeScript枚举既是值也是类型,因此您不需要再使用typeof
了。您可以直接将其用作类型,如下所示:
export interface FailedAction {
readonly type: type.FAILED;
}
文档:枚举
这正是string
枚举的设计初衷。在我看来,这是更好的方法,但还有另一个解决方案值得一提。
2( 作为常量
您可以使用as const
:将变量声明为文字只读
export const type = {
SUCCEEDED: 'type_SUCCEEDED',
FAILED: 'type_FAILED'
} as const;
文档:const
断言