函数重载的类型限制表现奇怪

问题描述 投票:1回答:1

我有这些:

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

typescript generics
1个回答
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:Action Type):Action;。如果你改变这样的界面

export interface ActionType<T = null> { val(): T; }

编译器显示错误

“ActionType”类型的参数不能分配给“ActionType”类型的参数。

Empty interface allow any object?

但是,如果要将动作动画与动作参数类型相关联,则使用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]) { 
 //...   
}
© www.soinside.com 2019 - 2024. All rights reserved.