You can make your union more stricted:
type PropsType = { top: number } | { bottom: number }
// credits goes to Titian Cernicova-Dragomir
//https://stackoverflow.com/questions/65805600/struggling-with-building-a-type-in-ts#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>
// A funtion that make something run at one direction by distance.
function run(props: StrictUnion<PropsType>) {
}
run({ top: 100, bottom: 100 }) // error
run({ top: 100 }) // ok
run({ bottom: 100 }) // ok
If this line :
type UnionKeys<T> = T extends T ? keyof T : never;
Playground
is not clear for you, please refer to the docs
When conditional types act on a generic type, they become distributive when given a union type.
If we plug a union type into ToArray, then the conditional type will be applied to each member of that union.