Typescript 键入泛型并将其定义为可选
我有一个接受泛型的类Typescript 键入泛型并将其定义为可选,typescript,Typescript,我有一个接受泛型的类 interface Converter<T = Buffer> { uuid: string; decode?: (value: Buffer) => T; encode?: (value: T) => Buffer; } type Converters = Record<string, Converter<any>>; export default class Service<C extends Con
interface Converter<T = Buffer> {
uuid: string;
decode?: (value: Buffer) => T;
encode?: (value: T) => Buffer;
}
type Converters = Record<string, Converter<any>>;
export default class Service<C extends Converters> {
private converters?: Converters;
constructor(converters?: C) {
this.converters = converters;
}
}
这个
因为转换器是可选的
现在的问题是服务
类有一个名为读取
的方法,该方法将接受一个名为名称
的参数并返回一个值,名称
的类型和返回类型应基于此
- 哪些转换器已传递到
类服务
- 如果任何转换器已传递到
类服务
- read应仅接受转换器的键作为
参数名称
- read应返回与该名称对应的转换器的泛型类型
read
应接受任何字符串作为参数并返回缓冲区
所以如果我通过
const converters = {
manufacturer: {
uuid: "2a29",
decode: (buffer: Buffer) => buffer.toString()
},
model: {
uuid: "2a24",
decode: (buffer: Buffer) => buffer.readInt8(0)
}
}
const service = new Service(converters);
const serviceNoConverter = new Service();
这应该发生
const value = service.read("manufacturer");
// ^^^^^ type string
const value = service.read("model");
// ^^^^^ type number
const value = service.read("aassd");
// ^^^^^ type error, not manufacturer or model
const value = serviceNoConverter.read("asdasdasd")
// ^^^^^ type Buffer ^^^^^^^^^ any string is allowed
因此,在StackOverflow的帮助下(特别是在jcalz的帮助下,谢谢老兄),我做到了这一点:
我认为将
C
约束为转换器|未定义的
和未定义的
作为默认值应该有效。我还建议将成员变量更改为C
类型,因为它已被正确约束:
类服务{
专用转换器?:C;
构造函数(转换器?:C){
这个。转换器=转换器;
}
//...
}
这里的关键是,通过将默认值设置为undefined
,创建没有转换器的服务将导致类型:service
,而不是service
我认为将
C
约束为转换器|未定义
和未定义
作为默认值应该有效。我还建议将成员变量更改为C
类型,因为它已被正确约束:
类服务{
专用转换器?:C;
构造函数(转换器?:C){
这个。转换器=转换器;
}
//...
}
这里的关键是,通过将默认值设置为undefined
,创建没有转换器的服务将导致类型:service
,而不是service
操场上最初的问题是:
-过度复杂化。
-转换器
属性类型
正如卢卡斯盖特所指出的,转换器应为C型。
但是,undefined
的默认通用值不是必需的。
它也可以像这样工作:
...
class Service<C extends Converters> {
private converters?: C;
constructor(converters?: C) {
this.converters = converters;
}
public read<N extends keyof C>(name: N): C[N] {
...
}
}
。。。
班级服务{
专用转换器?:C;
构造函数(转换器?:C){
这个。转换器=转换器;
}
公开阅读(名称:N):C[N]{
...
}
}
操场上最初的问题是:
-过度复杂化。
-转换器
属性类型
正如卢卡斯盖特所指出的,转换器应为C型。
但是,undefined
的默认通用值不是必需的。
它也可以像这样工作:
...
class Service<C extends Converters> {
private converters?: C;
constructor(converters?: C) {
this.converters = converters;
}
public read<N extends keyof C>(name: N): C[N] {
...
}
}
。。。
班级服务{
专用转换器?:C;
构造函数(转换器?:C){
这个。转换器=转换器;
}
公开阅读(名称:N):C[N]{
...
}
}
Hey@Alexey,谢谢你,但是如果你这样做,当没有转换器被传递到服务时,你会得到任何作为返回类型Hey@Alexey,谢谢,但是如果你这样做,当没有转换器被传递到服务时,你会得到任何作为返回类型
const converters = {
manufacturer: {
uuid: "2a29",
decode: (buffer: Buffer) => buffer.toString()
},
model: {
uuid: "2a24",
decode: (buffer: Buffer) => buffer.readInt8(0)
}
}
const service = new Service(converters);
const serviceNoConverter = new Service();
const value = service.read("manufacturer");
// ^^^^^ type string
const value = service.read("model");
// ^^^^^ type number
const value = service.read("aassd");
// ^^^^^ type error, not manufacturer or model
const value = serviceNoConverter.read("asdasdasd")
// ^^^^^ type Buffer ^^^^^^^^^ any string is allowed
...
class Service<C extends Converters> {
private converters?: C;
constructor(converters?: C) {
this.converters = converters;
}
public read<N extends keyof C>(name: N): C[N] {
...
}
}