我想创建一个通用函数来在 typescript-redux 中创建操作。
我想要的是使用传递接口作为类型变量的函数。所以我从这个功能开始:
function action<F>(type: string, payload: any): F {
return { type, payload };
}
Run Code Online (Sandbox Code Playgroud)
我想像这样使用它:
interface Login {
type: LOGIN_REQUEST;
payload: credentials;
}
const Login = (credentials: Credentials)
=> action<Login>(LOGIN_REQUEST, credentials);
Run Code Online (Sandbox Code Playgroud)
问题是有这个错误:
Type '{ type: string; payload: any; }' is not assignable to type 'F'.
Run Code Online (Sandbox Code Playgroud)
由于action是泛型,编译器确实无法知道对象文字{ type: string; payload: any; }是否满足 type F。此代码也将是一个有效的调用:
action<{ type: string; payload: any; otherMandatoryProp: boolean }>(LOGIN_REQUEST, credentials);
Run Code Online (Sandbox Code Playgroud)
F在上述情况下有额外的字段action不会填写。
在这种情况下,最简单的解决方案是跳出类型安全沙箱并使用类型断言:
function action<F>(type: string, payload: any): F {
return { type, payload } as any;
}
Run Code Online (Sandbox Code Playgroud)
这个版本仍然允许调用,{ type: string; payload: any; otherMandatoryProp: boolean }这可能会导致一些人对重新调整的对象上的字段做出一些假设。如果你想限制F到类型的只是type和payload你可以使用一个类型约束,它指定的属性type和payload存在于F和是否存在任何其他属性他们是类型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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5372 次 |
| 最近记录: |