typescript-如何在特定位置扩展接口(扩展库xstate的基本状态)

时间:2019-06-30 17:43:18

标签: typescript interface xstate

我希望能够在一个或多个特定位置扩展基本接口。这个想法是为了能够为库xstate定义一个基本状态,该状态可以扩展用于更特定的目的。

我有

SwingUtilities.invokeLater(() -> {
    JFrame obj = new JFrame();
    Gameplay gamePlay = new Gameplay();
    obj.setBounds(10, 10, 700, 600);
    obj.setTitle("Brick Breaker");
    obj.setResizable(false);
    obj.setVisible(true);
    obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    obj.add(gamePlay);
});

我想知道打字稿是否可能在特定位置扩展基本接口。例如“闲置”属性

interface Base {
   id:string;
   states:{
       init:{},
       loading:{},
       idle:{
            states:{
                  someBaseState:{}
            }

       }
   }
}

这样结果就是

interface Page "extends Base Idle Property" {
   id:string;
   states:{
       someOtherState:{}
   }
}

我知道我可以像这样在Typescript中定义泛型

{
   id:string;
   states:{
       init:{},
       loading:{},
       idle:{
            id:string;
            states:{
                someBaseState:{}
                someOtherState:{}
            }
       }
   }
}

但是我希望能够为状态“ idle”定义特定的基本属性(例如),而不是每次都完全实现它。

1 个答案:

答案 0 :(得分:0)

给出以下定义:

interface Base {
  id: string;
  states: {
    init: {};
    loading: {};
    idle: {
      states: {
        someBaseState: {};
      };
    };
  };
}

interface Page {
  id: string;
  states: {
    someOtherState: {};
  };
}

最简单的方法可能是使用intersection而不是继承,例如:

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
}

该类型可能很难理解为整形……如果您真的想要,可以像这样使用嵌套的mapped type

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;
        };
    };
}

无论哪种方法都可以。希望能有所帮助;祝你好运!

Link to code