Typescript的并集和交集不出错



我想有一个类型,以确保一个对象有ABA and B的类型。但是有一个案例我认为不应该失败。我敢肯定这是什么愚蠢的东西,只是我还看不出来。

interface ValueSelector
{
type: "id" | "value_string"
value: string
}
interface TemporalSelector
{
id: number
}
type Selector = (ValueSelector & TemporalSelector) | ValueSelector | TemporalSelector
// Should error
const e0: Selector = {}
const e1: Selector = { id: 0, value: "" }  // <-- does not error
const e2: Selector = { type: "id" }
const e3: Selector = { type: "value_string" }
const e4: Selector = { value: "" }
const e5: Selector = { value: "" }
// Should pass
const a1: Selector = { id: 0 }
const a2: Selector = { type: "id", value: "" }
const a3: Selector = { type: "value_string", value: "" }
const a4: Selector = { id: 0, type: "id", value: "" }
const a5: Selector = { id: 0, type: "value_string", value: "" }

e1不会触发错误,因为{ id: 0, value: "" }已经可分配给TemporalSelector,因为它只期望id属性。

为了使它工作,你可以使用StrictUnion帮助器:

interface ValueSelector {
type: "id" | "value_string"
value: string
}
interface TemporalSelector {
id: number
}
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>

type Selector = (ValueSelector & TemporalSelector) | StrictUnion<ValueSelector | TemporalSelector>
// Should error
const e0: Selector = {}
const e1: Selector = { id: 0, value: "" }  // error
const e2: Selector = { type: "id" }
const e3: Selector = { type: "value_string" }
const e4: Selector = { value: "" }
const e5: Selector = { value: "" }
// Should pass
const a1: Selector = { id: 0 }
const a2: Selector = { type: "id", value: "" }
const a3: Selector = { type: "value_string", value: "" }
const a4: Selector = { id: 0, type: "id", value: "" }
const a5: Selector = { id: 0, type: "value_string", value: "" }

游乐场

相关内容

  • 没有找到相关文章

最新更新