// utils.d.ts
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (Without<T, U> & U) | (Without<U, T> & T);
// component.tsx
type DefaultProps = {
instantPopoup?: boolean;
// ...
}
type PropsWithCb = { cb(): void; }
type PropsWithPath = { path: string; }
type Props = DefaultProps & XOR<PropsWithCb, PropsWithPath>;
const fn = (props: Props): void => {}
const p1: Props = { instantPopoup: true, path: "/test" }; // good
const p2: Props = { instantPopoup: false, cb: () => {} }; // good
fn({ instantPopoup: false, path: "/test" }); // good
fn({ instantPopoup: false, cb: () => {} }); // good
const error1: Props = { instantPopoup: true, path: "/test", cb: () => {} }; // error
const error2: Props = { instantPopoup: true }; // error
fn({ instantPopoup: false, cb: () => {}, path: "" }); // error
fn({ instantPopoup: false }); // error
Еще как вариант можно использовать это:
https://github.com/maninak/ts-xor