Машинопись - как расширить интерфейс в определенном месте (расширить базовое состояние для библиотеки xstate)
Я хочу иметь возможность расширить базовый интерфейс в одном или нескольких конкретных местах. Идея состоит в том, чтобы иметь возможность определить базовое состояние для библиотеки xstate, которое может быть расширено для более конкретных целей.
у меня есть
interface Base {
id:string;
states:{
init:{},
loading:{},
idle:{
states:{
someBaseState:{}
}
}
}
}
Я хочу знать, возможно ли с машинописью расширить базовый интерфейс в определенном месте. например, свойство "простоя"
interface Page "extends Base Idle Property" {
id:string;
states:{
someOtherState:{}
}
}
так что результат
{
id:string;
states:{
init:{},
loading:{},
idle:{
id:string;
states:{
someBaseState:{}
someOtherState:{}
}
}
}
}
Я знаю, что могу определить общий в Typescript, как это
interface Base<T> {
id: string;
states: {
idle: T
}
}
Но я хочу иметь возможность определять конкретные базовые свойства для состояния "простоя" (например) и не реализовывать его каждый раз полностью.
1 ответ
Учитывая эти определения:
interface Base {
id: string;
states: {
init: {};
loading: {};
idle: {
states: {
someBaseState: {};
};
};
};
}
interface Page {
id: string;
states: {
someOtherState: {};
};
}
проще всего использовать пересечение вместо наследования, например так:
type MyNewType = Base & { states: { idle: Page } };
interface MyNewInterface extends MyNewType {} // if you want in interface
Вы можете видеть, что он соответствует желаемой форме:
function foo(mni: MyNewInterface) {
mni.states.init; // okay
mni.states.idle.id; // okay
mni.states.idle.states.someBaseState; // okay
mni.states.idle.states.someOtherState; // okay
}
Этот тип может быть немного сложным для понимания как пересечение... если вы действительно хотите, вы можете использовать вложенный отображенный тип, например так:
type NestedId<T> = T extends object ? { [K in keyof T]: NestedId<T[K]> } : T;
type NestedExtend<T, U> = NestedId<T & U>;
type MyNewType2 = NestedExtend<Base, { states: { idle: Page } }>;
который показывает следующий тип при проверке через IntelliSense:
// IntelliSense shows you
type MyNewType2 = {
id: string;
states: {
init: {};
loading: {};
idle: {
states: {
someBaseState: {};
someOtherState: {};
};
id: string;
};
};
}
В любом случае должно работать. Надеюсь, это поможет; удачи!