I have this interface:
export interface AuthBtn {
link: string,
text: string,
onClick: (p1?: object, p2?: object)=> void,
}
And either the link
or onClick
field will exist, and I want the interface
to only include either link
& text
or onClick
& text
How can I acheive this?
CodePudding user response:
You need a discriminated union.
export type AuthBtn =
| {
link: string,
text: string,
_tag: "link_text",
}
| {
onClick: (p1?: object, p2?: object)=> void,
text: string,
_tag: "onclick_text",
}
The discriminant is not strictly necessary, but really useful in lots of situations.
CodePudding user response:
You need a union, like
export type AuthBtn1 =
| {
text: string,
onClick: (p1?: object, p2?: object) => void,
} | {
text: string,
link: string,
}
declare let a1: AuthBtn1;
if ('link' in a1) {
a1
// ^?
// let a1: {
// text: string;
// link: string;
// }
}
If you don't like using in
operatorm you need a distinct union
export type AuthBtn2 =
| {
text: string,
onClick: (p1?: object, p2?: object) => void,
link?: never,
} | {
text: string,
link: string,
onClick?: never,
}
declare let a2: AuthBtn2;
if (a2.link) {
a2
// ^?
// let a2: {
// text: string;
// link: string;
// onClick?: undefined;
// }
}
(|
in the beginning is noop, just for aligning)