泛型类的可选方法参数的类型
Posted
技术标签:
【中文标题】泛型类的可选方法参数的类型【英文标题】:Type for Optional Method Argument of Generic Class 【发布时间】:2021-08-03 22:01:32 【问题描述】:我想知道是否有一种方法可以声明具有默认泛型类型的泛型类:
-
默认情况下允许在不传递参数的情况下调用类的方法
如果定义了另一个泛型类型,则只有在传递泛型类型的参数时才能调用该方法。
伪代码
class ClassA<MyGenericType = OptionalArgumentType>
public methodWithGenericArgument(argumentA: MyGenericType): void
// Do smth
//
const instanceX = new ClassA();
instanceX.methodWithGenericArgument(); // CORRECT! We use default optional argument type
//
const instanceY = new ClassA<NotOptionalArgumentType>();
instanceY.methodWithGenericArgument(); // ERROR! Compiler should throw an error here, because we defined NOT OPTIONAL type
//
const argumentValue: NotOptionalArgumentType;
const instanceZ = new ClassA<NotOptionalArgumentType>();
instanceZ.methodWithGenericArgument(argumentValue); // CORRECT! We pass argument with required value
【问题讨论】:
@OlegValter,感谢您发现错别字。固定。 【参考方案1】:通过一些技巧,您可以完成这项工作。配方包括:
never
作为泛型类型参数的默认类型
rest parameters 在 TS 3.0 中添加了元组类型
这个想法是有条件地在一个空元组和一个参数的元组之间切换(或更多,或几个条件 - 取决于你的实现)。这是它的样子:
class ClassA<MyGenericType = never>
public methodWithGenericArgument(...args: MyGenericType extends never ? [] : [MyGenericType]): void
// Do smth
type NotOptionalArgumentType = number;
const instanceX = new ClassA();
instanceX.methodWithGenericArgument(); // OK
instanceX.methodWithGenericArgument(15); // ERROR
const instanceY = new ClassA<NotOptionalArgumentType>();
instanceY.methodWithGenericArgument(); // ERROR
instanceY.methodWithGenericArgument(15); // OK
let argumentValue!: NotOptionalArgumentType;
const instanceZ = new ClassA<NotOptionalArgumentType>();
instanceZ.methodWithGenericArgument(); // ERROR
instanceZ.methodWithGenericArgument(argumentValue); // OK
Playground
【讨论】:
【参考方案2】:几乎。它不能是一个方法,而是一个碰巧有一个函数分配给它的属性。取决于你在做什么,它可能有效,也可能无效。
class ClassA<T = string>
kindaMethod: T extends string ? (() => void) : ((arg: T) => void ) = ((maybeArg?: T) =>
// do sth
) as any
const x = new ClassA()
x.kindaMethod()
x.kindaMethod('a') // correctly an error
const y = new ClassA<number>()
y.kindaMethod() // correctly an error
y.kindaMethod(1)
Playground
您还需要将“方法”强制转换为 any
,因此如果您确实尊重您从类中公开的公共 API,请注意其实现。
【讨论】:
以上是关于泛型类的可选方法参数的类型的主要内容,如果未能解决你的问题,请参考以下文章