我正在尝试安全地实现以下功能
type OneOrAll<T extends any[]> =
T extends { length: 1 } ? T[0] :
T
interface Foo {
// ...
}
declare function oneOrAll<A extends Foo[]>(...as: A): OneOrAll<A>;
应根据给定参数的长度返回Foo
或Foo[]
。例如
const x: Foo = oneOrAll(fooA);
const xs: Foo[] = oneOrAll(fooA, fooB);
类型已经可以解决了,但是我正在努力编写实现。我的第一次尝试是
function oneOrAll<A extends Foo[]>(...as: A): OneOrAll<A> {
if (as.length == 1) {
return as[0]; // Type 'Foo' is not assignable to type 'OneOrAll<A>'.
}
return as; // Type 'A' is not assignable to type 'OneOrAll<A>'.
// Type 'Foo[]' is not assignable to type 'OneOrAll<A>'.
}
但是,这不能与内联错误一起编译。实现此功能的正确方法是什么?
答案 0 :(得分:1)
您可以使用函数重写来实现您的功能:
function oneOrAll<A extends [Foo]>(x: A[0]): A[0]
function oneOrAll<A extends Foo[]>(...xs: A): A
function oneOrAll<A extends Foo[]>(...xs: A): A[0] | A {
if (xs.length === 1) {
return xs[0]
}
return xs
}
您得到以下结果:
declare const foo: Foo
const x = oneOrAll(foo) // Foo
const y = oneOrAll(foo, foo) // [Foo, Foo]