问题在于数组是一个对象,所以如果接受数组参数的重载不匹配,Typescript 将继续进行下一个接受对象的重载,并得出第一个参数与 @ 兼容的结论987654321@。
如果第一个参数是对象重载的数组,我们可以使用条件类型在第二个参数中引入不兼容。此外,如果您需要为数组推断出不止一种类型,则需要指定更多类型参数,(每种类型一个,直到合理数量的类型)
type Type<T> = new (...args:any[]) => T
type Type<T> = new (...args: any[]) => T
class C {
public foo<T, P extends object>(src: P, type: P extends any[] ? never : Type<T>): T;
public foo<T>(src: [any], type: [Type<T>]): [T];
public foo<T, T1>(src: [any, any], type: [Type<T>, Type<T1>]): [T, T1];
public foo<T, T1, T2>(src: [any, any, any], type: [Type<T>, Type<T1>, Type<T2>]): [T, T1, T2];
public foo<T = any>(src: T[], type: Type<T>[]): T[]; // catch all oveload for arrays
public foo(src: object | any[], type: Type<any> | Type<any>[]): any {
}
}
class MyClass { private x!: string }
class MyClass2 { private x!: string }
let c = new C;
c.foo({}, MyClass) // ok, return My Class
c.foo({}, [MyClass]) // error
c.foo([], MyClass) // error
c.foo([{}], [MyClass]) // ok returns [MyClass]
c.foo([{}, {}], [MyClass, MyClass2]) // ok returns [MyClass, MyClass2]
c.foo([{}, {}, {}], [MyClass, MyClass2, MyClass]) // ok returns [MyClass, MyClass2, MyClass]