3

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

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

现在,我想为参数设置一个默认值,然后 T 将由默认值的类型确定:

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

但这不会编译,因为它期望“字符串”匹配 T 而不是确定 T 是“字符串”。

一种解决方案是编写:

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');
}

但后来我需要一个不同的名字,这让我很困扰。

有一个更好的方法吗?

4

3 回答 3

4

类型部分可以使用默认的泛型类型参数来实现(从 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 });
于 2017-06-28T13:11:37.230 回答
2
myMethod<T>(param1: number, param2: T = 'myDefaultString'): T {
  return param2;
}

上面的代码确实是无效的,因为表达式inst.myMethod<number>(23)会有 type ,而在运行时number仍然是 a 。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;
}

此版本inst.myMethod<number>(23)无效,因为具有类型参数的签名需要第二个参数。

于 2017-10-24T20:27:16.557 回答
-4

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

    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;
    }
于 2017-06-28T13:59:57.770 回答