我最好试图强制执行项目中的输入,以便任何实现Animal的人必须提供此功能并确保该函数只能将Woof或Meow作为唯一参数并且必须返回只有一个Woof或Meow。
这里有一些示例代码与我在VSCode中使用的代码(使用TypeScript 2.4.1)相似(名称除外):
class Woof {
constructor(private a: boolean = true) {}
}
class Meow {
constructor(private b: string = "abc") {}
}
class Dog implements Animal {
doSomething(sound: Woof): Woof {
return new Woof();
}
}
class Cat implements Animal {
doSomething(sound: Meow): Meow {
return new Meow();
}
}
interface Animal {
doSomething: <T extends Woof | Meow>(input: T) => T;
}
如果我放弃它in the TypeScript playground,它会产生我没有错误的JavaScript。
然而,在VSCode中,我在Dog和Cat类下都有一条红色的波浪线,鼠标悬停读取以下所有内容:
Class&#39; Dog&#39;错误地实现了界面&#39; Animal&#39;。
财产类型&#39; doSomething&#39;是不相容的。
键入&#39;(声音:Woof)=&gt;汪&#39;不能分配给类型&#39;(输入:T)=&gt; T&#39 ;.
参数类型&#39;声音&#39;和&#39;声音&#39;是不相容的。
键入&#39; T&#39;不能分配给#of; Woof&#39;。
类型&#39; Woof |喵&#39;不能分配给#of; Woof&#39;。
键入&#39; Meow&#39;不能分配给#of; Woof&#39;。
财产&#39; a&#39;类型&#39; Meow&#39;
中缺少
每个错误都是嵌套的,因此很难在此处准确显示格式,但它似乎表明我在扩展泛型时不能指定Woof或Meow类型,因为私有属性并未在两种类型中实现(看起来类似于another question here)。尽管文档中没有看到任何表明这是非法的内容(同样,在操场上,这似乎没有问题)。但是,与那个问题不同,我不希望泛型扩展这两种类型,而是被限制在一种或那种中。
在关于交集类型的帖子中阅读描述,它读取&#34;联合类型A | B表示类型A或类型B的实体,而交叉类型A&amp; B表示类型A和类型B&#34;的实体。读到这一点,我肯定想要一个工会类型,但这就是我上面所看到的,而且它似乎没有出现。
类型在备用类下的波浪形中翻转,但消息是相同的。
当我使用&#39; tsc&#39;实际构建项目时,我也会收到此错误在输出中。
我也尝试过实现以下内容,希望它能消除私有属性在Woof和Meow类之间匹配的奇怪需求(如果在指定每个类时出现意外情况,那么):
interface Sound {
}
class Woof implements Sound {
constructor(private a: boolean = true) {}
}
class Meow implements Sound {
constructor(private b: string = "abc") {}
}
class Dog implements Animal {
doSomething(sound: Woof): Woof {
return new Woof();
}
}
class Cat implements Animal {
doSomething(sound: Meow): Meow {
return new Meow();
}
}
interface Animal {
doSomething: <T extends Sound>(input: T) => T;
}
我得到的错误与以前完全相同。
现在,如果我只是完全消除泛型并仅使用上面替代的接口,它解决了部分目标,因为我可以将参数和结果限制为实现接口的类,但是&#39;不完全理想,因为它不会阻止另一个开发人员在一个接口实现中传递并尝试返回另一个接口实现。
interface Sound {
}
class Woof implements Sound {
constructor(private a: boolean = true) {}
}
class Meow implements Sound {
constructor(private b: string = "abc") {}
}
class Dog implements Animal {
doSomething(sound: Woof): Woof {
return new Woof();
}
}
class Cat implements Animal {
doSomething(sound: Meow): Meow {
return new Meow();
}
}
interface Animal {
doSomething: (input: Sound) => Sound;
}
我更喜欢使用泛型的类型安全性并将T限制为一种实现方式。有关如何使用泛型的任何想法,使用Typescript实际上可以在操场外使用的语法?
答案 0 :(得分:2)
这对你有用吗?
class Woof {
constructor(private a: boolean = true) { }
}
class Meow {
constructor(private b: string = "abc") { }
}
class Dog implements Animal<Woof> {
doSomething(sound: Woof): Woof {
return new Woof();
}
}
class Cat implements Animal<Meow> {
doSomething(sound: Meow): Meow {
return new Meow();
}
}
interface Animal<T extends Meow | Woof> {
doSomething(input: T): T;
}