TypeScript 3.0 中数组的泛型
Generics for Arrays in TypeScript 3.0
所以我看到 3.0 附带了剩余参数的通用类型,所以你可以这样做:
static identity<T extends any[]>(...values: T): T;
是否有可能为数组参数获得类似的东西,或者目前是否有我不知道的东西在起作用?例如,如果您查看 es6-promise declarations
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>, T10 | Thenable<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
static all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
static all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>;
static all<T1, T2, T3, T4, T5, T6>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>;
static all<T1, T2, T3, T4, T5>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>]): Promise<[T1, T2, T3, T4, T5]>;
static all<T1, T2, T3, T4>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>]): Promise<[T1, T2, T3, T4]>;
static all<T1, T2, T3>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>]): Promise<[T1, T2, T3]>;
static all<T1, T2>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>]): Promise<[T1, T2]>;
static all<T1>(values: [T1 | Thenable<T1>]): Promise<[T1]>;
static all<TAll>(values: Array<TAll | Thenable<TAll>>): Promise<TAll[]>;
Promise.all
的规范是它接受一个可迭代的参数而不是 rest 参数。不必写出所有这些类型真的很好,但根据我对 TypeScript 3.0 的高等教育知识,这还不可能。我说得对吗?
2019-10-06 更新:是的,从 TS3.1 开始这是可能的。
请参阅 this issue and this comment 以了解在您要推断的内容的上下文中包含元组类型的技巧。像这样:
declare function all<T extends any[] | []>( // note | [] here
values: T
): Promise<{ [K in keyof T]: T[K] extends Thenable<infer R> ? R : T[K] }>;
请注意类型 any[] | []
与 any[]
没有太大区别(类型 []
可分配给 any[]
,因此 any[] | []
实际上是与 any[]
) 相同的类型集,但提到空元组 []
会提示编译器您希望 T
尽可能被推断为元组。并且有效:
declare const thenableString: Thenable<string>;
const a = all(["hey", thenableString, 123]); // Promise<[string, string, number]>;
参见 link to code in Playground。
下面的旧答案:
我认为 TypeScript 3.1 将引入 tuple mapping,这将有助于部分解决这个问题。但不幸的是,我不知道有什么方法可以在不使用剩余参数的情况下将类似数组的函数参数推断为元组。我现在能得到的最接近你想要的(使用 typescript@next
来获取映射的元组)是:
declare function all<T extends any[]>(
values: T
): Promise<{[K in keyof T]: T[K] extends Thenable<infer R> ? R : T[K]}>;
function tuple<T extends any[]>(...args: T) { return args};
declare const thenableString: Thenable<string>;
const a = all(tuple("hey",thenableString,123)); // Promise<[string, string, number]>;
如果我找到更好的解决方案,我会考虑更多并编辑答案。
更新:目前看来不可能。值不会被推断为元组。这是一个 long-standing issue which was (originally) considered to be intentional behavior... Now that tuples are getting more powerful, there's another more recent GitHub issue 询问这个问题,并在评论中具体参考了 Promise.all
如何需要它。如果你关心它,你可能想去那个问题并给它一个或参与讨论。
希望对您有所帮助。祝你好运。
所以我看到 3.0 附带了剩余参数的通用类型,所以你可以这样做:
static identity<T extends any[]>(...values: T): T;
是否有可能为数组参数获得类似的东西,或者目前是否有我不知道的东西在起作用?例如,如果您查看 es6-promise declarations
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>, T10 | Thenable<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
static all<T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>, T9 | Thenable<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
static all<T1, T2, T3, T4, T5, T6, T7, T8>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>, T8 | Thenable<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>;
static all<T1, T2, T3, T4, T5, T6, T7>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>, T7 | Thenable<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>;
static all<T1, T2, T3, T4, T5, T6>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>, T6 | Thenable<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>;
static all<T1, T2, T3, T4, T5>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>, T5 | Thenable<T5>]): Promise<[T1, T2, T3, T4, T5]>;
static all<T1, T2, T3, T4>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>, T4 | Thenable <T4>]): Promise<[T1, T2, T3, T4]>;
static all<T1, T2, T3>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>, T3 | Thenable<T3>]): Promise<[T1, T2, T3]>;
static all<T1, T2>(values: [T1 | Thenable<T1>, T2 | Thenable<T2>]): Promise<[T1, T2]>;
static all<T1>(values: [T1 | Thenable<T1>]): Promise<[T1]>;
static all<TAll>(values: Array<TAll | Thenable<TAll>>): Promise<TAll[]>;
Promise.all
的规范是它接受一个可迭代的参数而不是 rest 参数。不必写出所有这些类型真的很好,但根据我对 TypeScript 3.0 的高等教育知识,这还不可能。我说得对吗?
2019-10-06 更新:是的,从 TS3.1 开始这是可能的。
请参阅 this issue and this comment 以了解在您要推断的内容的上下文中包含元组类型的技巧。像这样:
declare function all<T extends any[] | []>( // note | [] here
values: T
): Promise<{ [K in keyof T]: T[K] extends Thenable<infer R> ? R : T[K] }>;
请注意类型 any[] | []
与 any[]
没有太大区别(类型 []
可分配给 any[]
,因此 any[] | []
实际上是与 any[]
) 相同的类型集,但提到空元组 []
会提示编译器您希望 T
尽可能被推断为元组。并且有效:
declare const thenableString: Thenable<string>;
const a = all(["hey", thenableString, 123]); // Promise<[string, string, number]>;
参见 link to code in Playground。
下面的旧答案:
我认为 TypeScript 3.1 将引入 tuple mapping,这将有助于部分解决这个问题。但不幸的是,我不知道有什么方法可以在不使用剩余参数的情况下将类似数组的函数参数推断为元组。我现在能得到的最接近你想要的(使用 typescript@next
来获取映射的元组)是:
declare function all<T extends any[]>(
values: T
): Promise<{[K in keyof T]: T[K] extends Thenable<infer R> ? R : T[K]}>;
function tuple<T extends any[]>(...args: T) { return args};
declare const thenableString: Thenable<string>;
const a = all(tuple("hey",thenableString,123)); // Promise<[string, string, number]>;
如果我找到更好的解决方案,我会考虑更多并编辑答案。
更新:目前看来不可能。值不会被推断为元组。这是一个 long-standing issue which was (originally) considered to be intentional behavior... Now that tuples are getting more powerful, there's another more recent GitHub issue 询问这个问题,并在评论中具体参考了 Promise.all
如何需要它。如果你关心它,你可能想去那个问题并给它一个或参与讨论。
希望对您有所帮助。祝你好运。