考虑这个例子:
type ItemNew = { text: string };
type ItemExist = { text: string, id: number };
type Union = ItemNew | ItemExist
declare var union: Union
const elem = union.text // only text property is allowed
因为text 对这两个项目都是通用的,所以您可以获取text 属性。
因为没有人知道var union 是否包含id。在这种情况下允许 id 属性是不合理的(可能会导致运行时错误)。
让我们回到你的例子:
type ItemNew = { text: string };
type ItemExist = { text: string, id: number };
function fn(
itemsNew: Array<ItemNew>,
itemsExist: Array<ItemExist>
) {
const items = [...itemsNew, ...itemsExist];
}
实际上items 是Array<ItemNew> | Array<ItemExist> 的联合。应用相同的规则。财产text 是唯一安全的财产。
如果你想获得id proeprty,你可能不会使用这个助手:
type ItemNew = { text: string };
type ItemExist = { text: string, id: number };
// credit goes to https://stackoverflow.com/questions/65805600/type-union-not-checking-for-excess-properties#answer-65805753
type UnionKeys<T> = T extends T ? keyof T : never;
type StrictUnionHelper<T, TAll> =
T extends any
? T & Partial<Record<Exclude<UnionKeys<TAll>, keyof T>, never>> : never;
type StrictUnion<T> = StrictUnionHelper<T, T>
function fn(
itemsNew: Array<ItemNew>,
itemsExist: Array<ItemExist>
) {
const items: Array<StrictUnion<ItemNew | ItemExist>> = [...itemsNew, ...itemsExist];
items[0].text // ok
items[0].id // number | undefined
}