泛型类的可选方法参数的类型

问题描述

我想知道是否有一种方法可以声明一个具有认泛型类型的泛型类:

  1. 认情况下将允许在不传递参数的情况下调用类的方法
  2. 如果定义了另一个泛型类型,则只有在传递泛型类型的参数时才能调用方法

代码

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

解决方法

通过一些技巧,您可以完成这项工作。配方包括:

  1. never 作为泛型类型参数的默认类型
  2. 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

,

差不多。它不能是一个方法,而是一个属性,它恰好有一个分配给它的功能。取决于你在做什么,它可能有效,也可能无效。

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,请注意其实现。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...