具有类型或接口的TypeScript分解的默认参数

时间:2019-12-02 21:22:36

标签: typescript types interface optional destructuring

我正在编写一个带有可选对象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可能不存在。

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

在使用类型或接口时是否有任何标准方法可以解决此问题?

1 个答案:

答案 0 :(得分:3)

通过options在参数列表中的myFoo: Foo参数 的类型推断为Params | 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 = {}) => {};