Typescript 嵌套类型脚本泛型

Typescript 嵌套类型脚本泛型,typescript,generics,nested-generics,Typescript,Generics,Nested Generics,我有以下课程: class Walls { } class Furniture { } class Layout<T extends Walls | Furniture> { } class Space extends Layout<Walls> { } class Room extends Layout<Furniture> { } 因为Layout需要一个类型参数 我可以创建以下内容: class LayoutController<U, T ext

我有以下课程:

class Walls { }
class Furniture { }
class Layout<T extends Walls | Furniture> { }
class Space extends Layout<Walls> { }
class Room extends Layout<Furniture> { }
因为
Layout
需要一个类型参数

我可以创建以下内容:

class LayoutController<U, T extends Layout<U extends Walls | Furniture>>{ }

如果正确指定了类型约束,再多键入一点两种类型的参数解决方案是不错的,并且如果
U
与布局所期望的
T
不兼容,则会给您带来适当的错误:

class Walls { height!: number; }
class Furniture { price!: number; }
class Layout<T extends Walls | Furniture> { children: T[] = []; }
class Space extends Layout<Walls> { private x: undefined; }
class Room extends Layout<Furniture> { private x: undefined; }

class LayoutController<U extends Walls | Furniture, T extends Layout<U>>{
    getValue(u: U) : void{}
}

class SpaceController extends LayoutController<Walls, Space> { }
class RoomController extends LayoutController<Furniture, Room> {}
class ErrController extends LayoutController<Walls, Room> {}  //Type 'Room' does not satisfy the constraint 'Layout<Walls>
我们也可以使用条件类型而不是
U
,因此不允许用户将
U
更改为布局所接受的派生类型(取决于您的用例特性或您决定的设计限制):

type ExtractLayoutParameter=T扩展布局?U:从来没有;
类布局控制器{
getValue(u:ExtractLayoutParameter):void{}
}
类SpaceController扩展了LayoutController{}
类RoomController扩展了LayoutController{}
新建SpaceController().getValue(新墙())
new SpaceController().getValue(new Furniture())//错误

如果正确指定了类型约束,则再多键入一点两种类型的参数解决方案是不错的,如果
U
与布局所期望的
T
不兼容,则会给您带来适当的错误:

class Walls { height!: number; }
class Furniture { price!: number; }
class Layout<T extends Walls | Furniture> { children: T[] = []; }
class Space extends Layout<Walls> { private x: undefined; }
class Room extends Layout<Furniture> { private x: undefined; }

class LayoutController<U extends Walls | Furniture, T extends Layout<U>>{
    getValue(u: U) : void{}
}

class SpaceController extends LayoutController<Walls, Space> { }
class RoomController extends LayoutController<Furniture, Room> {}
class ErrController extends LayoutController<Walls, Room> {}  //Type 'Room' does not satisfy the constraint 'Layout<Walls>
我们也可以使用条件类型而不是
U
,因此不允许用户将
U
更改为布局所接受的派生类型(取决于您的用例特性或您决定的设计限制):

type ExtractLayoutParameter=T扩展布局?U:从来没有;
类布局控制器{
getValue(u:ExtractLayoutParameter):void{}
}
类SpaceController扩展了LayoutController{}
类RoomController扩展了LayoutController{}
新建SpaceController().getValue(新墙())
new SpaceController().getValue(new Furniture())//错误

能否提供有关
LayoutController
实施的更多详细信息?似乎它可以定义为
类LayoutController
,但也许我遗漏了什么。@AlekseyL。它是一个React组件,在状态中有一个名为selected layout的字段类LayoutController扩展React.Component(){}接口LayoutController状态{selectedLayout:T;}```确定,因此可以将内部布局字段键入为
layout
,其中
T
LayoutController
@AlekseyL的通用参数。注释中的格式被破坏。请查看问题本身中的编辑。@AlekseyL。这意味着我必须编写
class SpaceController extensed LayoutController{}
,而不是
LayoutController
。您能否提供有关
LayoutController
实现的更多详细信息?似乎它可以定义为
类LayoutController
,但也许我遗漏了什么。@AlekseyL。它是一个React组件,在状态中有一个名为selected layout的字段类LayoutController扩展React.Component(){}接口LayoutController状态{selectedLayout:T;}```确定,因此可以将内部布局字段键入为
layout
,其中
T
LayoutController
@AlekseyL的通用参数。注释中的格式被破坏。请查看问题本身中的编辑。@AlekseyL。这意味着我必须编写
class SpaceController extensed LayoutController{}
,而不是
LayoutController
,谢谢您的详细回答!我不知道Typescript中有这么多内容:)在使用条件类型、推断等之前,我会阅读更多内容。但现在,您的双参数解决方案很简单。谢谢@阿卜杜勒·萨塔尔默罕默德(AbdulsattarMohammed),还有更多的字体;-)。感谢您的详细回复!我不知道Typescript中有这么多内容:)在使用条件类型、推断等之前,我会阅读更多内容。但现在,您的双参数解决方案很简单。谢谢@阿卜杜勒·萨塔尔默罕默德(AbdulsattarMohammed),还有更多的字体;-)。
class SpaceController extends LayoutController<Walls, Space> { }
class RoomController extends LayoutController<Furniture, Room> {}
class RoomController extends LayoutController<Walls, Room> {}
class LayoutController<T> extends React.Component<{}, LayoutControllerState<T>>() { }
interface LayoutControllerState<T> { 
  selectedLayout: T;
}
class Walls { height!: number; }
class Furniture { price!: number; }
class Layout<T extends Walls | Furniture> { children: T[] = []; }
class Space extends Layout<Walls> { private x: undefined; }
class Room extends Layout<Furniture> { private x: undefined; }

class LayoutController<U extends Walls | Furniture, T extends Layout<U>>{
    getValue(u: U) : void{}
}

class SpaceController extends LayoutController<Walls, Space> { }
class RoomController extends LayoutController<Furniture, Room> {}
class ErrController extends LayoutController<Walls, Room> {}  //Type 'Room' does not satisfy the constraint 'Layout<Walls>
type ExtractLayoutParameter<T extends Layout<any>> = T extends Layout<infer U> ? U: never;
class LayoutController<T extends Layout<any>, U extends Walls | Furniture= ExtractLayoutParameter<T>>{
    getValue(u: U) : void{}
}

class SpaceController extends LayoutController<Space> { }
class RoomController extends LayoutController<Room> {}
new SpaceController().getValue(new Walls())
new SpaceController().getValue(new Furniture()) // error
type ExtractLayoutParameter<T extends Layout<any>> = T extends Layout<infer U> ? U: never;
class LayoutController<T extends Layout<any>>{
    getValue(u: ExtractLayoutParameter<T>) : void{}
}

class SpaceController extends LayoutController<Space> { }
class RoomController extends LayoutController<Room> {}
new SpaceController().getValue(new Walls())
new SpaceController().getValue(new Furniture()) // error