2

我在 TS 中使用类型注释作为某种文档。对我来说,很高兴知道我的函数将预先管理的类型。

我还没有找到一种方法来声明这种函数的类型。编译器推断出一个类型,但是当我尝试自己用相同的类型进行注释时,它会崩溃。

以这个函数为例:

// compiler infers the type
// f: ({ a }?: { a?: number | undefined }) => number
const f = ({ a = 0 } = {}) => a;

但是当我尝试注释它失败并出现以下错误。

const f: ({ a }?: { a?: number | undefined }) => number =
    ({ a = 0 } = {}) => a;
//     ^
//     \-- Property 'a' does not exist on type '{ a?: number | undefined; } | undefined'
4

2 回答 2

2

如果我理解您所说的正确,您应该能够将 替换{ a }为您选择的变量名称:

const f: (v?: {a?: number | undefined}) => number = ({ a = 0 } = {}) => a;

因为您在注释中描述参数的形状,所以不需要在参数声明中指定 a 是成员。

于 2020-03-06T15:14:26.710 回答
2

它看起来确实像是编译器中的一个错误,或者至少是一个不幸的限制。我还没有在 GitHub 中找到关于这种特殊情况的现有问题;microsoft/TypeScript#35160似乎是相关的,但并没有完全回答这样的事情是如何发生的。我已经提交了microsoft/TypeScript#37271以了解发生了什么;如果我得到更多信息,我会在这里更新。

更新:这是一个编译器错误,已在 TypeScript 3.9.1 中修复typescript@next并将随 TypeScript 3.9.1 一起发布。当它发布时,这里的答案将只是“更新您的 TS 版本”。对于以前的版本和其他相关方,剩下的答案仍然存在。


但是你的问题是如何注释,所以首先让我们确保编译器不是完全疯狂的,并且当你悬停时显示的类型f确实与它兼容:

const f = ({ a = 0 } = {}) => a;

const g: ({ a }?: { a?: number; }) => number = f; // no error

这样可行。所以问题一定是当你f显式地注释它的类型时,它为编译器不满意的参数提供了一个上下文类型(可能是错误的)。我能想到的解决方法是显式注释这个参数:

const h: ({ a }?: { a?: number }) => number =
  ({ a = 0 }: { a?: number } = {}) => a; // no error

所以这行得通。奇怪的是,您需要同时注释箭头函数及其参数,但至少您有一条前进的道路。希望有帮助;祝你好运!

Playground 代码链接

于 2020-03-07T13:28:34.037 回答