0

我希望能够在一个或多个特定位置扩展基本接口。这个想法是能够为库 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 中定义 Generic

interface Base<T> {
  id: string;
  states: {
    idle: T
  }
}

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

4

1 回答 1

0

鉴于这些定义:

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

无论哪种方式都应该有效。希望有帮助;祝你好运!

链接到代码

于 2019-06-30T19:09:00.397 回答