这是一个简单的示例代码:
interface Params {
a: string
b: number
c: boolean
}
const f1 = (p1: Params) => void;
const f2 = (p2: Params2) => f1({a: 'default', ...p2});
f2
用默认值填充Params.a
。因此,Params2
是Params
,a?: string
(a
是可选的)。
如何创建此Params2
而不手动列出a
,b
,c
?
我已经尝试了以下方法,但是它不起作用:
interface Params2 extends Params {
a?: string
}
使用Partial<T>
不好,因为它会使所有属性变为可选,而不是仅使a
为可选。
答案 0 :(得分:3)
使用conditional types(特别是Exclude
和mapped types(特别是Pick
和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
窄,因此虽然您无法通过扩展Params2
来获得Params
,但您可以进行相反操作:
interface Params2 {
a?: string
b: number
c: boolean
}
interface Params extends Params2 {
a: string
}
这可能适合您,也可能无法满足您的要求,但是它可能比上面的Optionalize
类型处理更直接。
希望有所帮助;祝你好运!