gpt4 book ai didi

typescript - 是否可以进行类型安全的节点式回调?

转载 作者:搜寻专家 更新时间:2023-10-30 21:24:22 25 4
gpt4 key购买 nike

节点回调看起来像这样:

interface NodeCallback<TResult,TError> {
(err: TError): void;
(err: null, res: TResult): void;
}

因此回调将得到 errres 但不会同时得到。我看到的大多数类型都将 errres 类型硬编码为它们的非可选版本。

function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void;

这不是严格类型安全的。例如,这编译得很好:

fs.readdir('/', (err, files) => {
if (err !== null) { // There's an error!
files.forEach(log); // Still using the result just fine.
}
})

您可以通过更改签名以包含所有可能的值来使其更(好吧,有点)安全。

function readdir(path: string, callback?: (err: null | NodeJS.ErrnoException, files?: string[]) => void): void;

但是没有办法指定两者之间的依赖关系,所以你需要键入 assert res 来安静 strictNullChecks

fs.readdir('/', (err, files) => {
if (err === null) { // There's no error
// files.forEach(log); // Won't compile
(files as string[]).forEach(log); // Type assertion
files!.forEach(log); // Nice shorthand
if (files !== undefined) { // Type guard
files.forEach(log);
}
}
})

这还算不错,除了:

  • 当你需要重复做的时候。
  • 当您不访问某个属性时,您必须键入断言,这可能意味着您需要导入另一种类型。真的很烦人。类型保护会避免这种情况,但你会得到不必要的运行时间惩罚。
  • 它实际上仍然不安全。它更直接,因此您不得不考虑它,但我们主要依赖手动断言。

如果你真的想要,你可以用一个Result-like discriminated union来做到这一点:

type Result<R,E>
= { error: false, value: R }
| { error: true, value: E }

function myFunction(callback: (res: Result<string, Error>) => void) {
if (Math.random() > 0.5) {
callback({ error: true, value: new Error('error!') });
} else {
callback({ error: false, value: 'ok!' })
}
}

myFunction((res) => {
if (res.error) {
// type of res.value is narrowed to Error
} else {
// type of res.value is narrowed to string
}
})

老实说,这最终是相当不错的,但这是很多样板文件,完全违背了常见的节点风格。

所以我的问题是 typescript 目前是否有办法使这种 super 常见的模式既安全又方便?我很确定现在的答案是否定的,这没什么大不了的,但我只是好奇。

谢谢!

最佳答案

除了你所做的,我见过的唯一好的模式是这样的:

function isOK<T>(err: Error | null, value: T | undefined): value is T {
return !err;
}

declare function readdir(path: string, callback: (err: null | Error, files: string[] | undefined) => void): void;

readdir('foo', (err, files) => {
if (isOK(err, files)) {
files.slice(0);
} else {
// need to err! here but 'files' is 'undefined'
console.log(err!.message);
}
})

关于typescript - 是否可以进行类型安全的节点式回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39801062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com