我有这些:
export interface ActionType<T = null> extends String {}
dispatch(type: ActionType<null>): ActionT<null>;
dispatch<TPayload>(type: ActionType<TPayload>, payload: TPayload): ActionT<TPayload>;
dispatch<TPayload>(action: ActionType<TPayload>, payload?: TPayload) {
// implementation
}
const TEST_ACTION: ActionType<string> = 'TEST_ACTION';
当我使用以下命令调用此函数时:
dispatch(TEST_ACTION)
我希望这不会编译,因为它需要有一个有效负载。但是它没有选择dispatch(type: ActionType<null>): ActionT<null>;
重载事件,尽管有一个TPayload
而不是null
。
有没有办法进一步限制类型?
链接到游乐场示例:here
答案 0 :(得分:0)
代码包含非常具体的界面
export interface ActionType<T = null> extends String {}
ActionType可分配给ActionType,而ActionType可分配给ActionType
let v1: ActionType<null> = 'v1';
let v2: ActionType<string> = 'v2';
v1 = v2; // no errors
v2 = v1; // no errors
因此,编译器首先从签名列表中选择: dispatch(type:ActionType):ActionT; 。如果您这样更改界面
export interface ActionType<T = null> { val(): T; }
然后编译器显示错误
“ ActionType”类型的参数无法分配给参数 类型为“ ActionType”。
请参见Empty interface allow any object?
但是,如果要使用动作参数类型关联actio名称,请使用keyof功能。
// params
interface CreateUserAction {
name: string;
password: string;
}
interface DeleteUseAction {
id: string;
}
// params map
interface ActionMap {
'create': CreateUserAction;
'delete': DeleteUseAction;
}
// function
function dispatch<K extends keyof ActionMap>(type: K, actionParams: ActionMap[K]) {
//...
}
dispatch('create', { name: 'hey', password: '1' });
// generic version
function dispatchG<TM, K extends keyof TM>(type: K, actionParams: TM[K]) {
//...
}