我想为第一个元素是特定类型(例如Function)的数组定义一个类型,其余元素是空类型。例如:
type FAs = [Function, {}, {}, {}, ...]; // pseudo code
这样的事情可能吗?
目的是提供这样的单参数函数:
const myCaller = ([fun, ...args]: FAs) => fun.apply(args);
另一种方法是使用myCaller
的两个参数,如下所示:
const myCaller = (fun: Function, args: any[]) => fun.apply(args);
但出于审美原因,我宁愿使用单一论点。我也想知道类型系统是否支持可以说是任意长度的元组。也许出于我不理解的计算机科学原因,这样的事情是不可取的。
答案 0 :(得分:11)
如果你定义
type FAs = [Function, {}];
然后,类型FAs
的值将需要类型为Function
的第一个元素,类型为{}
的第二个元素,以及Function | {}
的后续元素。这就是TypeScript文字数组类型的工作方式。来自TS docs:
当访问已知索引集之外的元素时,将使用联合类型:
这应该做你想要的一切除了,因为你可以传递一个Function
类型的值作为数组的第三个元素等。但实际情况确实如此,因为Function
与{}
兼容。
没有办法解决这个问题。 TS中没有办法定义一个数组类型,其中第一个 n 元素属于某些特定类型,并且存在任意数量的其他特定类型的剩余元素。
我也想知道类型系统是否支持可以说是任意长度的元组。
实际上,类型系统仅支持任意长度的元组。如果你说
type Tuple = [number, number];
此类型与任何长度为2的或更高的数组兼容,其中包含数字。如果你说
type Tuple = [string, number];
此类型与任何长度为或更长的数组兼容,其中第一个元素为字符串,第二个为数字,第三个为字符串或数字等。我不会把这种行为的原因称为“基于计算机科学”;这更多的是TS检查的可行性。
interface Arglist {
[index: number]: object;
0: Function;
}
const a1: Arglist = [func];
const a2: Arglist = [22]; // fails
const a3: Arglist = [func, "foo"]; // fails
const a4: Arglist = [func, obj];
const a5: Arglist = [func, obj, obj];
答案 1 :(得分:4)
在当前版本的Typescript中,可以使用数组扩展来实现:
type FAs = [Function, ...Array<{}>]
它支持1到n之间的任何长度(必填第一个元素)。
答案 2 :(得分:0)
我很确定这是你可以做的最好的打字稿2.3。你可以在lodash中看到这样的类型。
{{1}}
答案 3 :(得分:0)
我还想知道类型系统是否支持可以说是任意长度的元组。
从TS 4.0开始,您可以使用variadic tuple types。
例如,以类型安全的方式声明[func, ...<proper func args>]
:
type FAs<A extends unknown[], R> = [(...args: A) => R, ...A]
const myCaller = <A extends unknown[], R>([fn, ...args]: FAs<A, R>) =>
fn.apply(null, args)
例:
const fn1 = (a1: string, a2: number) => true
const r1 = myCaller([fn1, "foo", 42]) // OK, r1 has type `boolean`
const r2 = myCaller([fn1, "foo", "bar"]) // error, `bar` has wrong type
const r3 = myCaller([fn1, "foo"]) // error, not enough arguments
答案 4 :(得分:0)
type First<T> = T extends [infer U, ...any[]] ? U : any;
type F = First<[number, boolean, string]> // number