【问题标题】:TypeScript destructured default parameter with type or interfaceTypeScript 使用类型或接口解构默认参数
【发布时间】:2020-03-27 12:50:09
【问题描述】:

我正在编写一个函数,它接受一个可选对象options,它本身包含一个可选属性params。这个options 对象有一个默认值{},所以它可以在函数签名中被正确地解构。

但是,我在尝试使用界面键入时遇到了问题:

type Params = {
  params?: { [key: string]: boolean }
}

interface Foo {
  (options?: Params): void
};

const myFoo: Foo = ({ params } = {}) => {} // Property 'params' does not exist on type 'Params | undefined'.

这个错误是有道理的:据编译器所知,options 可能是未定义的(当参数设置为 optional 时由它解释),所以params 可能不存在它。

但是,它没有考虑到 可选 参数可能具有默认值。然而,我还没有找到一种在类型或接口中正确指示这一点的方法。直接在函数签名中输入确实有效,但不能重复使用或导出。

在使用类型或接口时,有什么标准方法可以解决这个问题吗?

【问题讨论】:

    标签: typescript types interface optional destructuring


    【解决方案1】:

    options 参数的类型推断在参数列表中 通过myFoo: FooParams | undefined,不管实现中是否提供了默认值。只有在myFoo 的主体中,它才会将options 推断为Params,因为默认值:

    // hover over options here: Params | undefined
    const myFoo: Foo = (options = {}) => {
      // hover over options here: Params
      options;
    };
    

    要解决这个问题,请推迟对象解构,直到 options 的类型完全从实现的默认值推断出来:

    // no error
    const myFoo: Foo = (options = {}) => {
      const { params } = options;
    };
    

    或者正如您已经发现的那样,您可以通过将参数显式键入为Params 来帮助进行类型推断。不过,这可能会在某些情况下误导编译器:

    // no error
    const myFoo: Foo = ({ params }: Params = {}) => {};
    

    【讨论】:

    • 谢谢,这很有意义。我不知道编译器是否可以从签名中推断出来,但这似乎不太可能,所以在所有都是可选的情况下,我猜在签名中解构不是一种选择。
    • 看来这个推理问题已经在 TypeScript 3.9.7 中得到了修复。如果您打开此示例并切换到早期版本(即 3.8.3),您将看到再次标记错误:typescriptlang.org/play?ts=3.9.7#code/…
    猜你喜欢
    • 2013-09-09
    • 2021-12-22
    • 2018-09-15
    • 2016-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多