Javascript 使用泛型类型扩展接口的Typescript会导致约束错误的子类型

Javascript 使用泛型类型扩展接口的Typescript会导致约束错误的子类型,javascript,typescript,class,types,abstract-class,Javascript,Typescript,Class,Types,Abstract Class,我有一个抽象类,其默认状态值在ResourceState接口中键入。当我尝试将扩展的State分配给抽象类的State属性时,出现了以下错误。我尝试了许多不同的方法使用交叉点,尽管它仍然不起作用。我想要实现的是,我可以为state属性提供一个通用接口,这样我就可以在默认值之外添加更多的值 这是我得到的错误: 类型“{items:never[];isLoading:false;错误:string;}”不可分配给类型“State”。 “{items:never[];isload:false;erro

我有一个抽象类,其默认状态值在
ResourceState
接口中键入。当我尝试将扩展的
State
分配给抽象类的State属性时,出现了以下错误。我尝试了许多不同的方法使用交叉点,尽管它仍然不起作用。我想要实现的是,我可以为state属性提供一个通用接口,这样我就可以在默认值之外添加更多的值

这是我得到的错误:

类型“{items:never[];isLoading:false;错误:string;}”不可分配给类型“State”。 “{items:never[];isload:false;error:string;}”可分配给类型为“State”的约束,但“State”可以用约束“ResourceState”的不同子类型实例化

这是我的代码:

导出接口基本项{
id:字符串;
名称:字符串;
}
导出接口ResourceState{
项目:项目[];
选择编辑项?:项目;
isLoading:布尔值;
错误:字符串;
}
导出抽象类资源,突变,getter,Actions>{
state:state={//这是发生错误的地方
项目:[],
孤岛加载:false,
错误:“”,
}

}
当你说
状态扩展了ResourceState
时,你是说
状态
需要符合
资源状态
,但由于这是一个泛型类型参数,它可能不完全是
资源状态

想象一下:

interface MyState extends ResourceState<{ a: 123 }> {
  myCustomRequiredProperty: number
}
然后,您的
状态
变量将不会使用
myCustomRequiredProperty
属性构造,这是必需的

这就是typescript试图(秘密地)告诉您的错误


如果您正在
资源
类中构造状态变量,则
状态
不应是泛型的,因为此类中的可执行代码无法知道可以泛型传入的类型的所有属性。所以
State
不应该
扩展ResourceState
,它应该是一个
ResourceState

看起来是这样的:

export abstract class Resource<Item extends BaseItem> {
  state: ResourceState<Item> = {
    items: [],
    isLoading: false,
    error: '',
  }
}
导出抽象类资源{
状态:ResourceState={
项目:[],
孤岛加载:false,
错误:“”,
}
}


但是,如果您希望能够将属性添加到状态,那么在没有一些初始值的情况下就无法做到这一点。您需要以某种方式初始化这些未知属性。要做到这一点,您可以使用上面的方法,但是使用一个构造函数,该构造函数接受任何类型的完整状态,然后使用具有该信息的对象填充该类型的未知属性

export abstract class Resource<
  Item extends BaseItem,
  State extends ResourceState<Item>
> {
  state: State

  constructor(initialState: State) {
    this.state = {
      ...initialState, // Fills in extended properties
      items: [],
      isLoading: false,
      error: '',
    }
  }
}
导出抽象类资源<
项目扩展了基本项目,
状态扩展资源状态
> {
州:州
构造函数(initialState:State){
此.state={
…initialState,//填充扩展属性
项目:[],
孤岛加载:false,
错误:“”,
}
}
}

export abstract class Resource<
  Item extends BaseItem,
  State extends ResourceState<Item>
> {
  state: State

  constructor(initialState: State) {
    this.state = {
      ...initialState, // Fills in extended properties
      items: [],
      isLoading: false,
      error: '',
    }
  }
}