简体   繁体   English

如何在Typescript中定义一个类,该类接受一个接口,该接口具有两个用于相同泛型的字段并保证它们是同一类型?

[英]How do I define a class in Typescript that accepts an interface that has two fields for the same generic and guarantee they are the same type?

I apologize for the confusing wording in the title, I'm having a hard time coming up with a one line summary for the question. 对于标题中的措辞令人困惑,我深表歉意,我很难为这个问题写一个单行摘要。 Here is an example to explain what I'm trying to do: 这是一个示例,解释我要执行的操作:

interface Fish {
    type: 'fish';
}

interface Dog {
    type: 'dog';
}

type Animal = Fish | Dog;

interface MatingPair<T> {
    animal: T;
    otherAnimal: T;
}

class AnimalCollection<T> {
    private pairs: T[] = [];
    addPair<V extends T>(subject: V) {
        this.pairs.push(subject);
    }
}

let td = new AnimalCollection<MatingPair<Animal>>();

// Correctly generates error, dog is not a fish
td.addPair<MatingPair<Fish>>({
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
});

// Incorrectly lets dogs and fish be a mating pair
td.addPair({
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
});

I would like to be able to declare that addPair should receive a version of MatingPair that not just contains two "animals", but that the two animals are the same type. 我希望能够声明addPair应该收到一个MatingPair版本,该版本不仅包含两个“动物”,而且两个动物是同一类型。

Right now this code properly verifies that the call to td.addPair on the last line is receiving two animals of the same type (fish, in this case), but only because I'm explicitly setting T to be Fish . 现在,此代码正确地验证了对最后一行td.addPair的调用是否正在接收两个相同类型的动物(在这种情况下为fish),但这只是因为我将T明确设置为Fish Is there a way to define this such that I can say both that MatingPair.animal & MatingPair.otherAnimal both have values that are types within the union Animal, but also that the type is the same for both of them? 有没有一种方法可以这样定义,我可以说MatingPair.animalMatingPair.otherAnimal都具有在联合动物中属于类型的值,而且两者的类型都相同?

You can reach your goal by restructuring the definition of the Animal collection class a bit like so: 您可以通过如下方式重构Animal集合类的定义来实现您的目标:

interface Fish {
    type: 'fish';
}

interface Dog {
    type: 'dog';
}

type Animal = Fish | Dog;

interface MatingPair<T> {
    animal: T;
    otherAnimal: T;
}

class AnimalCollection<T>
{
    private pairs: MatingPair<T>[] = [];
    addPair<V extends T>(subject: MatingPair<V>)
    {
        this.pairs.push(subject);
    }
}

let td = new AnimalCollection<Animal>();

// Correctly generates error, dog is not a fish
td.addPair<Fish>({
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
});

// Correctly generates error, dog is not a fish
td.addPair({
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
});

Its not 100% what you ask for - but will solve the problem. 它不是您要求的100%,但可以解决问题。

A little bit of explanation. 一点解释。 Basically in your sample you are trying to do this: 基本上在您的示例中,您正在尝试执行以下操作:

let a: MatingPair<Animal> = {
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
}

And this is perfectly legal because both animal and otherAnimal are of type Animal , just different animals. 这是完全合法的,因为animalotherAnimal都是Animal类型,只是不同的动物。

Whereas my subtle change makes code to look more like this: 而我的细微更改使代码看起来更像这样:

let a: MatingPair<Dog> = {
  animal: { type: 'dog' },
  otherAnimal: { type: 'fish' }
}

And this is wrong as fish is not a dog. 这是错误的,因为鱼不是狗。

In the real sample idea is the same, its just instead of Dog I have put there requirement that V is descendant of Animal . 在实际示例中想法是相同的,只是我代替了Dog要求VAnimal后代。 So either Dog or Fish but not both as they are incompatible. 因此,无论是Dog还是Fish但都不是两者,因为它们不兼容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Typescript 两个接口属性相同泛型,需要相同类型 - Typescript Same generic in two interface properties, require same type 如何让 Typescript 识别联合中两个相同类型接口之间的通用共性? - How to get Typescript to recognise generic commonalities between two of the same type of interface in a union? 如何在打字稿中定义匿名通用接口? - How do I define an anonymous generic interface in typescript? 我可以定义两个具有相同属性但值不同的接口的联合类型吗? - Can I define a union type of two interface that has same property but different values? TypeScript:是否可以强制接口签名中的泛型类型与实现此接口的 class 类型相同 - TypeScript: is it possible to force a generic type in a interface signature that be of the same type of class that implements this interface 我可以在一个类中定义一个特定的类类型,该类在打字稿中实现了一个具有泛型类型的接口吗? - Can I define a specific class type in a class that implements an interface with a generic type in typescript? 如何确定两个对象是否具有相同的类型(打字稿) - How do I determine if two objects are of the same type (typescript) Typescript 如何扩展使用泛型类型的接口? - Typescript how do I extend an interface which uses a generic type? 如何键入与 object 具有相同属性的 class? - How do I type a class that has the same properties as an object? 我可以为类的方法定义通用的打字稿接口吗? - Can I define a generic typescript Interface for the methods of a Class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM