首页 > 解决方案 > Typescript中的对象休息之类的东西?类似于部分

问题描述

这是一个简单的示例代码:

interface Params {
  a: string
  b: number
  c: boolean
}

const f1 = (p1: Params) => void;

const f2 = (p2: Params2) => f1({a: 'default', ...p2});

f2填充Params.a默认值。因此,Params2is Paramswith a?: string(a是可选的)。

如何在Params2不手动列出的情况下创建它a,,?bc

我尝试了以下方法,但它不起作用:

interface Params2 extends Params {
  a?: string
}

使用Partial<T>是不好的,因为它使所有属性都是可选的,而不是只是a可选的。

标签: typescript

解决方案


使用条件类型(特别是Exclude)和映射类型(特别是Pickand Partial),您可以表达采用现有类型并有选择地将其某些属性转换为可选属性的想法:

type Optionalize<T, K extends keyof T> = 
  Pick<T, Exclude<keyof T, K>> & Partial<Pick<T, K>>

这基本上是说,Optionalize<T, K>当您取出带有键的属性K并将它们设为可选时,您会得到什么,而其余所有属性都保持原样。

interface Params2 extends Optionalize<Params, 'a'> {}

您可以验证这Params2相当于

{a?: string, b: number, c: boolean}

如预期的。


一个不同的想法:你Params实际上比你更窄Params2,虽然你不能通过 extends 得到Params2Params可以做相反的事情:

interface Params2 {
  a?: string
  b: number
  c: boolean
}
interface Params extends Params2 {
  a: string
}

这可能适合您,也可能不适合您,但它可能比Optionalize上面的类型杂耍更直接。


希望有帮助;祝你好运!


推荐阅读