打字稿中有类似对象的东西吗?类似于Partial <t>

时间:2018-07-10 20:45:09

标签: 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。因此,Params2Paramsa?: stringa是可选的)。

如何创建此Params2而不手动列出abc

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

interface Params2 extends Params {
  a?: string
}

使用Partial<T>不好,因为它会使所有属性变为可选,而不是仅使a为可选。

1 个答案:

答案 0 :(得分:3)

使用conditional types(特别是Excludemapped types(特别是PickPartial),您可以表达采用现有类型并有选择地选择的想法将其某些属性转换为可选属性:

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窄,因此虽然您无法通过扩展Params2来获得Params,但您可以进行相反操作:

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

这可能适合您,也可能无法满足您的要求,但是它可能比上面的Optionalize类型处理更直接。


希望有所帮助;祝你好运!