Cамое простое — это использовать миксины
и объединения
одновременно, миксинами задаем 4 возможных варианта:
left
и top
не заданы
- только
left
задан
- только
top
задан
left
и top
заданы
а union
позволит TS
выбирать между ними. Все работает как нужно в качестве ошибок, но есть и ложка дегтя в этом решении — ошибки отображаются не совсем точно, например:
const t3: test = {
offsetTop: 1
}
Type '{ offsetTop: number; }' is not assignable to type 'test'.
Type '{ offsetTop: number; }' is missing the following properties from type 'Base4': top, left
const t4: test = {
offsetLeft: 1
}
Type '{ offsetLeft: number; }' is not assignable to type 'test'.
Type '{ offsetLeft: number; }' is missing the following properties from type 'Base4': top, left
(Другие варианты проходят без ошибок можно посмотреть тут)
Если такая точность ошибки не смущает, решение можно считать рабочим.
Весь код:
type Top = {
top: number;
offsetTop?: number;
}
type Left = {
left: number;
offsetLeft?: number;
}
type Behavior = {
behavior?: "auto" | "smooth"
}
interface Base1 extends Behavior {}
interface Base2 extends Top, Behavior {}
interface Base3 extends Left, Behavior {}
interface Base4 extends Top, Left, Behavior {}
type test = Base1 | Base2 | Base3 | Base4