我想创建一个类型,如果在另一个类型中定义了相同的属性,该类型将出错。这是为了构建一个类型安全的合并(也许已经有一个?)以下工作,但我想知道是否有更好的方法?是否存在实现无法处理的极端情况?
type UniqueObject<T extends {[K in keyof U]?: any}, U> = {[K in keyof U]: undefined extends T[K] ? U[K]: never}
function safeMerge <T, U, V, W> (a: T, b?: UniqueObject<T, U>, c?: UniqueObject<T & U, V>, d?: UniqueObject<T & U & V, W>) {
return { ...a, ...b, ...c, ...d /* etc */ }
}
safeMerge({ ar: 1 }, { ar: 2 }) // errors correctly
safeMerge({ ar: 1 }, { ar: undefined }) // errors correctly
safeMerge({ ar: 1 }, { b: 2 }) // works correctly
safeMerge({ ar: 1 }, { b: 2 }, { ar: 3 }) // errors correctly
safeMerge({ ar: 1 }, { b: 2 }, { b: undefined }) // errors correctly
safeMerge({ ar: 1 }, { b: 2 }, { c: 3 }) // works correctly
safeMerge({ ar: 1 }, { b: 2 }, { c: 3 }, { ar: 1 }) // errors correctly
safeMerge({ ar: 1 }, { b: 2 }, { c: 3 }, { d: 4 }) // works correctly
我认为这个的数学描述是 set difference (wikipedia) .
最佳答案
native utility types 中不存在这样的安全合并,虽然一些类似的类型可能存在于库中,例如 piotrwitek/utility-types , 我没有看到任何实现这种类型。
此外,因为传播运算符只复制 "own enumerable properties" ,您应该可以安全地使用该实现。
关于 typescript 类型在属性的交集上出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57036430/