Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 泛型可以有几个特定类型的约束而不进行扩展吗?_Typescript - Fatal编程技术网

Typescript 泛型可以有几个特定类型的约束而不进行扩展吗?

Typescript 泛型可以有几个特定类型的约束而不进行扩展吗?,typescript,Typescript,我的目标是使用严格的类型来确保对象的格式正确。我希望能够指定一些必须遵循的有效格式并加以实施 interface TypeA { A: void; } interface TypeB { B: void; } interface TypeC { C: void; } type Type = TypeA | TypeB | TypeC; interface BaseItem<T extends Type> { name: string; data: T; } type Item

我的目标是使用严格的类型来确保对象的格式正确。我希望能够指定一些必须遵循的有效格式并加以实施

interface TypeA { A: void; }
interface TypeB { B: void; }
interface TypeC { C: void; }

type Type = TypeA | TypeB | TypeC;

interface BaseItem<T extends Type> { name: string; data: T; }

type Item = BaseItem<TypeA> | BaseItem<TypeB> | BaseItem<TypeC>;

const collection: Item[] = [
  { name: 'A', data: { A: null } },
  { name: 'B', data: { B: null } },
  { name: 'C', data: { C: null } },
];

class Example<T extends Type> {
  item: BaseItem<T>;

  add(item: BaseItem<T>) {
    this.item = item;
    collection.push(item); // Error on `item`

    /**
     * Argument of type 'BaseItem<T>' is not assignable to parameter of type 'Item'.
     *   Type 'BaseItem<T>' is not assignable to type 'BaseItem<TypeA>'.
     *     Type 'T' is not assignable to 'TypeA'.
     *       Type 'Type' is not assignable to type 'TypeA'.
     *         Property 'A' is missing in the type 'TypeB' but required in type 'TypeA'.
     */
  }
}
接口类型A{A:void;}
接口类型B{B:void;}
接口类型C{C:void;}
类型=类型A |类型B |类型C;
接口BaseItem{name:string;data:T;}
类型项=基本项|基本项|基本项;
常量集合:项[]=[
{name:'A',数据:{A:null}},
{name:'B',数据:{B:null},
{name:'C',数据:{C:null},
];
课例{
项目:基本项目;
添加(项目:基本项目){
this.item=项目;
collection.push(item);//关于`item'的错误`
/**
*“BaseItem”类型的参数不能分配给“Item”类型的参数。
*类型“BaseItem”不可分配给类型“BaseItem”。
*类型“T”不可分配给“TypeA”。
*类型“Type”不可分配给类型“TypeA”。
*类型“TypeB”中缺少属性“A”,但类型“TypeA”中需要属性“A”。
*/
}
}
在上面的代码中,类型
用于强制执行
集合
数组中对象的格式。这让我了解了我计划如何使用这种格式

同样在上面的代码中,我尝试对
示例
类使用泛型。我的想法是,我可能需要我的类的几个属性,以确保它们在任何给定时刻都使用共享泛型。尽管泛型扩展了有效类型,但我知道它在理论上可以支持它以外的类型(例如,
BaseItem&{more:string}

我理解为什么它在当前状态下不工作。我不明白的是我将如何实现我想要的


有没有办法使用泛型来严格匹配一种类型的联合,而不是扩展一种类型的联合?比如,不是
,而是有类似
的东西吗?或者,有不同的方法来处理这个问题吗?

我不知道如何将其分类,一个限制?但在我看来,这辆车有问题。以下是您可以修复它的方法:

interface TypeA { A: void; }
interface TypeB { B: void; }
interface TypeC { C: void; }

type Type = TypeA | TypeB | TypeC;

interface BaseItem<T extends Type> { name: string; data: T; }

type Item = BaseItem<TypeA> | BaseItem<TypeB> | BaseItem<TypeC>;

const collection: Item[] = [
  { name: 'A', data: { A: null } },
  { name: 'B', data: { B: null } },
  { name: 'C', data: { C: null } },
];

class Example<T extends Type> {
  item: BaseItem<T>;

  // notice this conditional type, see the irony here?
  // everything `extends any`, so this expression reduce to
  // just `BaseItem<T>`, never `never`, so why the trouble?
  add(item: T extends any ? BaseItem<T> : never) {
    this.item = item;
    collection.push(item);  // cus this way error magically disappear :)
  }
}
接口类型A{A:void;}
接口类型B{B:void;}
接口类型C{C:void;}
类型=类型A |类型B |类型C;
接口BaseItem{name:string;data:T;}
类型项=基本项|基本项|基本项;
常量集合:项[]=[
{name:'A',数据:{A:null}},
{name:'B',数据:{B:null},
{name:'C',数据:{C:null},
];
课例{
项目:基本项目;
//注意这个条件类型,看到这里的讽刺了吗?
//everything'extensed any',因此此表达式简化为
//只是'BaseItem',从来没有'never',那么为什么会有麻烦呢?
添加(项:T扩展任何?基本项:从不){
this.item=项目;
collection.push(item);//这样错误会神奇地消失:)
}
}

我有点厌倦了使用TS时所涉及的所有技巧。这是,是的,又是一个花哨的名字,如果你感兴趣,请点击。就我个人而言,我不知道如何为这种行为辩护。

你到底想解决什么问题?当前代码产生错误,因为
BaseItem
Item
的子类型,而不是相反。我不明白为什么
Type
有问题?如果你想
t是Type
,那么你不需要一个通用的cus,你已经知道它是
Type
。最终目标是使用
t
类型使类具有多个属性和方法。这将允许任何子类更加具体(例如,
特定于类的扩展示例{…}
),并强制遵守指定的任何类型,那么我就无法确保在一个应该只使用
TypeA
的子类中,使用
TypeA
而不是
TypeB
。那么你已经得到了你想要的,
意味着你所说的
。正如我所说,您得到的错误与
T
无关,我对TS处理泛型类型param的当前行为不满意。即使有这么强的约束,它也不能确定所有内容。链接让我意识到我可以使用该技术创建一个
ItemByType
distributive条件类型,其值为
T extends TypeA?BaseItem:…
用于所有项目类型。有点。。。冗长,但它有效。@KOVIKO upvote/accept如果能帮助您,那就太好了。我觉得我不能接受这个答案,因为我不确定在此上下文中使用
any
的含义。但是投票是值得的!