typescript - 子一个函数的参数的可选性取决于其他函数打字稿的参数的可选性
问题描述
我正在创建一个函数示例,它将函数 fn1 作为参数并返回函数 fn2;
type Values<T> = (values: T) => Promise<void>; //function with argument
type NoValues = () => Promise<void>; //function without arguments
type Func1<T> = Values<T> | NoValues;
let example = function <T, R extends Func1<T> = Func1<T>>(fn1: R) {
const fn2 = async (values: R extends Values<T> ? T : void) => {
await fn1(values);
}
return fn2;
}
fn1 应该采用一个可选参数。根据 fn1 是否有可选参数,fn2 也应该有。所以如果 fn1 没有任何参数,那么 fn2 也不应该有它们,反之亦然。
我尝试用多种方式编写这样的限制,但仍然无法成功。如果有人帮助我,我会很高兴。
interface IExample {
whatever: string;
}
const test1_fn1 = async () => console.log("");
const test1_fn2 = example<IExample>(test1_fn1);
test1_fn2() //Should work, but does not. Expected 1 argument. Not intended
const test2_fn1 = async (values: IExample) => console.log(values);
const test2_fn2 = example<IExample>(test2_fn1);
test2_fn2() //Should not work, does not work, as intended
test2_fn2({whatever: ""}) //Should work, works, as intended
TS 版本:3.8.3。这里是游乐场
解决方案
重载可能最简单:
type Values<T> = (values: T) => Promise<void>; //function with argument
type NoValues = () => Promise<void>; //function without arguments
type Func1<T> = Values<T> | NoValues;
function makeFn2<T>(fn1: NoValues): NoValues;
function makeFn2<T>(fn1: Values<T>): Values<T>;
function makeFn2<T>(fn1: Func1<T>): Func1<T> {
return async (...values: [T?]) => {
await (fn1 as any)(...values);
}
}
declare const argFunc: Values<string>;
const argFunc2=makeFn2(argFunc);
argFunc2("s");
argFunc2(); // error
declare const noArgFunc: NoValues;
const noArgFunc2=makeFn2(noArgFunc);
noArgFunc2();
noArgFunc2("asd"); // error
它在编译和运行时都应该是正确的,即只有当 fn2 被调用时才使用参数调用 fn1。
推荐阅读
- javascript - 将 npm 包编译成单个 js 文件
- angularjs - Angular Overlay withTransformOriginOn 用法
- asp.net-core - 如何订阅 MS Graph 日历(不是日历事件)更改通知,即创建/删除新日历等?
- python - sklearn.manifold.SpectralEmbedding() 距离度量
- reactjs - 如何在 React 中单独更改每个页面上的元数据
- javascript - 如何通过 sourcemaps 在浏览器中访问原始源文件
- postman - 无法从邮递员中的 pm.sendRequest() 获取响应 json
- java - 运行测试时,预计至少有 1 个 bean 有资格作为自动装配候选者
- java - 发送 HTTP 响应而不等待方法 Spring Webflux Rest 的执行
- laravel - 私人频道在带有推送器的 laravel 中不起作用