如果我们有
interface Human{
name:string
age:number
dimensions : {
height:number
width:number
}
}
const base : Human ={
name:"Base",
age:12,
dimensions : {
height:190,
width:99
}
};
const child : Human = lodashMerge(base,{
age:22,
dimentions:{
height:99
}
}) // this should work , shouldn't throw
const child2 : Human = lodashMerge(base,{
hairColor:'red'
}) // should throw because hairColor does not exist in base
答案 0 :(得分:2)
假设lodashMerge
是lodash的_.merge
方法,您将无法执行此操作并继续单独使用该方法。你必须将它包装到你自己的函数中,你可以添加更严格的类型定义,因为lodash本身给出的定义过于宽松。
The type definition for that method can be found here,正如您所看到的,每个重载的返回类型只是其参数的交集类型,听起来您希望返回类型恰好是第一个参数的类型。
所以我建议使用你想要的签名将方法包装到你自己的函数中。这样的事情可能是:
// Using only the final overload (the variadic one), since thats how we call it later.
declare function lodashMerge(object: any, ...otherArgs: any[]): any;
type DeepPartial<T> = {
[K in keyof T]?: DeepPartial<T[K]>;
}
function myMerge<T>(base: T, ...args: DeepPartial<T>[]): T {
return lodashMerge(base, ...args);
};
然后,使用它,您将在第二个示例中出现错误,但不会在第一个示例上出现错误。 虽然实际上,由于拼写错误的“尺寸”,因此两者都会出错:
// No problem, works as expected.
const child : Human = myMerge(base,{
age:22,
dimensions:{ // Note the change in spelling, otherwise: error.
height:99
}
})
// Error: See below
const child2 : Human = myMerge(base,{
hairColor:'red' // Error: Object literal may only specify known properties, and 'hairColor' does not exist in type 'DeepPartial<Human>'.
})
答案 1 :(得分:0)
您的示例代码遗漏了确定是否将检测到错误的位。这取决于lodashMerge
的定义方式。
如果要传递部分对象,请将Partial<Human>
视为lodashMerge
函数的参数类型。否则,您可以{ age: 99 } as any
绕过类型检查。