Javascript 表示泛型变量数的TypeScript类型注释?
我一直在把我的一个项目从JavaScript转换成TypeScript, 但这种类型的注释让我感到困惑。 我有一个Javascript 表示泛型变量数的TypeScript类型注释?,javascript,typescript,Javascript,Typescript,我一直在把我的一个项目从JavaScript转换成TypeScript, 但这种类型的注释让我感到困惑。 我有一个序列化程序接口和一个用于组合这些接口的类,如下所示: interface Serializer<T> { serialize(value: T): ArrayBuffer } class UnionSerializer { constructor(types) { this.types = types } serializ
序列化程序
接口和一个用于组合这些接口的类,如下所示:
interface Serializer<T> {
serialize(value: T): ArrayBuffer
}
class UnionSerializer {
constructor(types) {
this.types = types
}
serialize(value) {
for (const type of this.types) {
try {
return type.serialize(value) //throws error if type can't serialize value
}
catch (e) {}
}
throw new Error('No type matched')
}
}
为
UnionSerializer
类编写类型注释最优雅的方法是什么,理想情况下不必为类型的不同长度的数组编写所有构造函数注释?新UnionSerializer([a,b])
的类型与新UnionSerializer的类型之间是否存在差异([b,a])
?它看起来并不真实,因为您的UnionSerializerConstructor
的类型签名返回一个序列化程序。相反,只需接受一个数组:
interface UnionSerializerConstructor {
new <T>(types: T[]): Serializer<T>
}
我不妨继续为您键入UnionSerializer
:
class UnionSerializer<T> implements Serializer<T> {
constructor(public types: (Serializer<T>)[]) {
// next line is unnecessary with "public types" above
// this.types = types
}
serialize(value: T): ArrayBuffer {
for (const type of this.types) {
try {
return type.serialize(value) //throws error if type can't serialize value
}
catch (e) { }
}
throw new Error('No type matched')
}
}
(这种类型的缩小通常是不合理的,但TypeScript这样做是出于性能和开发人员方便的原因。虽然有,但它们还不是语言的一部分。)
也就是说,UnionSerializer
构造函数上的类型推断将:
但是,您可以手动指定它:
new UnionSerializer<string|number>([justNumberSerializer, justStringSerializer]); // ok
新UnionSerializer([justNumberSerializer,justStringSerializer]);//确定
这有点烦人,但很有效。可能有办法改善这种体验,但我现在不确定。这有帮助吗?是可序列化的只是序列化程序的一个输入错误吗?还是你在这里没有定义的一个单独类型?是的,输入错误,很抱歉谢谢你的回答!这是我最初的解决方案。专业版但我的问题是,并不是我传入的所有类型都必须是具有相同的T
的Serializer
。例如,我可能有一个Serializer
和一个Serializer
,因此联合所需的T
将是string | number
,而不是原始Serializer
的implement序列化程序
。这有意义吗?
class UnionSerializer<T> implements Serializer<T> {
constructor(public types: (Serializer<T>)[]) {
// next line is unnecessary with "public types" above
// this.types = types
}
serialize(value: T): ArrayBuffer {
for (const type of this.types) {
try {
return type.serialize(value) //throws error if type can't serialize value
}
catch (e) { }
}
throw new Error('No type matched')
}
}
declare const numberOrStringSerializer: Serializer<number | string>;
const justStringSerializer: Serializer<string> = numberOrStringSerializer;
const justNumberSerializer: Serializer<number> = numberOrStringSerializer;
new UnionSerializer([justNumberSerializer, justStringSerializer]); // error
new UnionSerializer<string|number>([justNumberSerializer, justStringSerializer]); // ok