确定泛型方法类型的默认参数

时间:2017-06-28 12:42:04

标签: typescript generics default-arguments typescript-generics

我定义了一个泛型方法,其泛型类型由以下参数之一确定:

myMethod<T>(param1: number, param2: T): T {
  return param2;
}

现在,我希望参数有一个默认值,然后T将由默认值的类型决定:

myMethod<T>(param1: number, param2: T = 'myDefaultString'): T {
  return param2;
}

但是这不会编译,因为它希望“string”匹配T而不是将T确定为'string'。

一种解决方案是写:

myMethod<T>(param1: number, param2: T = <any>'myDefaultString'): T {
  return param2;
}

但是我需要在调用站点明确指定类型:

const val: string = this.myMethod<string>();

我考虑的另一个解决方案是编写第二个函数,没有默认参数:

myMethod<T>(param1: number, param2: T): T {
  return param2;
}

myMethodDefault(param1: number): string {
  return myMethod(param1, 'myDefaultString');
}

但是我需要一个不同的名字,这让我感到困扰。

有更好的方法吗?

3 个答案:

答案 0 :(得分:3)

可以使用默认的泛型类型参数(因为TypeScript 2.3)来实现类型部分:

class Hey {
    myMethod<T = string>(arg1: number, arg2?: T): T {
        if (arg2 === undefined)
            // have to handle default parameter manually
            return "myDefaultString" as any as T;
        return arg2;
    }
}

const h = new Hey();

// n1: string;
const n1 = h.myMethod(1);
// n2: typeof "mm"
const n2 = h.myMethod(2, "mm");
// n3: { a: number }
const n3 = h.myMethod(3, { a: 1 });

答案 1 :(得分:2)

/home/john/wekafiles/packages/LibSVM/LibSVM.jar

上面的代码确实无效,因为表达式myMethod<T>(param1: number, param2: T = 'myDefaultString'): T { return param2; } 的类型为inst.myMethod<number>(23),而在运行时仍然是number

您可以使用签名重载解决此问题:

string

此版本使// with only one param, the return type is a string: myMethod(param1: number): string // with two params, use a type parameter: myMethod<T>(param1: number, param2: T): T myMethod(param1: number, param2: any = 'myDefaultString') { return param2; } 无效,因为带有类型参数的签名需要第二个参数。

答案 2 :(得分:-3)

你是对的,我不认为有一种方法可以做到这一点,而不会给你的课程带来不必要的复杂性。您可以检查内部类型,然后在特定情况下返回默认值。但是,我并不认为这样的检查也是一个很好的模式。

    static void Main(string[] args)
    {
        var p2 = "test";
        var p3 = 23;
        Console.WriteLine(myMethod<string>(0, p2));
        Console.WriteLine(myMethod<int>(0, p3));
        Console.WriteLine(myMethod(0, p2));
        Console.WriteLine(myMethod(0, p3));
        Console.ReadLine();
    }

    static public T myMethod<T>(int param1, T param2) 
    {
        return param2;
    }

    static public string myMethod(int param1, string param2)
    {
        return param2;
    }