在 TypeScript 中键入可为空的回调变量



是否可以在不牺牲类型安全性的情况下简化下面的 TypeScript 代码中resolve变量的声明?我是 TypeScript 的新手,请耐心等待。

目标是保存传递给执行器函数的 promise 解析器回调,以便稍后可以在它外部调用它。我想出的是let resolve: ((v: number) => void) | null = null.在 TS 游乐场尝试一下:

function timeout(ms: number): Promise<number> {
// save the promise's resolver to be invoked later
let resolve: ((v: number) => void) | null = null; // <===
const p = new Promise<number>(r => resolve = r);
const start = performance.now();
setTimeout(() => resolve!(performance.now() - start), ms);
return p;
}

如果我不把它变成带有null的联合类型,TypeScript 会合理地抱怨resolve在我稍后调用它时可能未初始化:setTimeout(() => resolve(...), ms)。有没有更简洁的方法可以做到这一点,而不会引入any或 TypeScript 错误?

澄清一下,上面的例子有点做作,可以很容易地简化为这样:

function timeout(ms: number): Promise<number> {
const start = performance.now();
return new Promise<number>(r => 
setTimeout(() => r(performance.now() - start)));
}

然而,问题是关于TypeScript语法的。实际代码确实需要保存承诺的resolvereject回调来实现Deferred模式。

使其更简洁的一种方法是删除null,并且一开始不为resolve分配任何内容:

function timeout(ms: number): Promise<number> {
let resolve: (v: number) => void;
const p = new Promise<number>(r => resolve = r);
const start = performance.now();
setTimeout(() => resolve(performance.now() - start), ms);
return p;
}

它可能看起来有点奇怪,但这确实适用于任何!断言。

如果您碰巧能够立即返回承诺,您可以将其精简到

function timeout(ms: number) {
let resolve: (v: number) => void;
return new Promise<number>(r => {
resolve = r;
const start = performance.now();
setTimeout(() => resolve(performance.now() - start), ms);
});
}

最新更新