繁体   English   中英

打字稿无法转换为通用类型变量

[英]typescript cannot cast to generic type variable

我想创建一个通用函数来在typescript-redux中创建动作。

我想要的是使用传递接口作为类型变量的函数。 所以我从这个功能开始:

function action<F>(type: string, payload: any): F {
    return { type, payload };
}

我想这样使用它:

interface Login {
    type: LOGIN_REQUEST;
    payload: credentials;
}

const Login = (credentials: Credentials) 
     => action<Login>(LOGIN_REQUEST, credentials);

问题是有此错误:

Type '{ type: string; payload: any; }' is not assignable to type 'F'.

由于action是通用的,因此编译器实际上无法知道对象文字{ type: string; payload: any; } { type: string; payload: any; } { type: string; payload: any; }将满足类型F 此代码也将是有效的调用:

action<{ type: string; payload: any; otherMandatoryProp: boolean }>(LOGIN_REQUEST, credentials);

在上述情况下, F具有多余的字段,因此无法执行action

最简单的解决方案是在这种情况下突破类型安全沙箱并使用类型断言:

function action<F>(type: string, payload: any): F {
    return { type, payload } as any;
}

此版本仍允许使用{ type: string; payload: any; otherMandatoryProp: boolean } { type: string; payload: any; otherMandatoryProp: boolean } { type: string; payload: any; otherMandatoryProp: boolean } ,这可能会使某些人对重新调整的对象上的字段进行一些假设。 如果要将F限制为仅具有typepayload的类型,则可以使用类型约束,该约束指定F存在属性typepayload ,并且如果存在任何其他属性,则它们的类型为never

function action<F extends { type : string, payload : any} & { [P in Exclude<keyof F, 'type' | 'payload'>]: never }>(type: string, payload: any): F {
    return { type, payload } as any;
}
const Login = (credentials: credentials) => action<Login>(LOGIN_REQUEST, credentials);
action<{ type: string; payload: any; otherMandatoryProp: boolean }>(LOGIN_REQUEST, {}) // invalid call

打字稿的返回值应与您要返回的对象匹配打字稿的返回值应为login类型(或者您可以将其设置为any)

function action<F>(type: string, payload: any): Login  {
    return { type, payload };
}

因为您将不会返回任何值,而只会返回Login ,所以您需要添加一个约束:

function action<F extends Login>(type: string, payload: any): F {
    return { type, payload } as F;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM